📄 vga.c
字号:
VGA_CREATEMODE(320,200,8,vga_write_pixel8,vga_setpal8,vga_setpalentry8,g_320x200x256),
VGA_CREATEMODE(320,200,8,vga_write_pixel8x,vga_setpal8,vga_setpalentry8,g_320x200x256_modex),
};
/*******************************
helper functions
*******************************/
void vga_write_regs(const unsigned char *regs)
{
unsigned char i;
/* write MISCELLANEOUS reg */
outb(MISCO_WRITE, *regs);
regs++;
/* write SEQUENCER regs */
for(i = 0; i < 5; i++)
{
outb(SQREG_ADDR, i);
outb(SQREG_DATA, *regs);
regs++;
}
/* unlock CRTC registers */
outb(CRTCR_ADDR2, 0x03);
outb(CRTCR_DATA2, inb(CRTCR_DATA2) | 0x80);
outb(CRTCR_ADDR2, 0x11);
outb(CRTCR_DATA2, inb(CRTCR_DATA2) & ~0x80);
/* make sure they remain unlocked */
//regs[0x03] |= 0x80;
//regs[0x11] &= ~0x80;
/* write CRTC regs */
for(i = 0; i < 25; i++)
{
outb(CRTCR_ADDR2, i);
outb(CRTCR_DATA2, *regs);
regs++;
}
/* write GRAPHICS CONTROLLER regs */
for(i = 0; i < 9; i++)
{
outb(GRREG_ADDR, i);
outb(GRREG_DATA, *regs);
regs++;
}
/* write ATTRIBUTE CONTROLLER regs */
for(i = 0; i < 21; i++)
{
(void)inb(0x3DA);
outb(ATTRC_ADDR, i);
outb(ATTRC_WRITE, *regs);
regs++;
}
/* lock 16-color palette and unblank display */
(void)inb(0x3DA);
outb(ATTRC_ADDR, 0x20);
}
void *vga_get_fb_addr(void)
{
DWORD seg;
outb(GRREG_ADDR, 6);
seg = inb(GRREG_DATA);
seg >>= 2;
seg &= 3;
switch(seg)
{
case 0:
case 1:
seg = 0xE00A0000;
break;
case 2:
seg = 0xE00B0000;
break;
case 3:
seg = 0xE00B8000;
break;
}
return (void*)seg;
}
void vga_set_plane(unsigned p)
{
/* set read plane */
outb(GRREG_ADDR, 4);
outb(GRREG_DATA, p);
/* set write plane */
outb(SQREG_ADDR, 2);
outb(SQREG_DATA, 1<<(p&3));
}
void vpokeb(int off, char v)
{
*((char*)vga_get_fb_addr()+off) = v;
}
char vpeekb(int off)
{
return *((char*)vga_get_fb_addr()+off);
}
/*******************************
mode specific functions
*******************************/
void vga_setpal8(const unsigned char *pal)
{
int i;
outb(DACRG_RESET,0xFF);
outb(DACRG_WMADDR,0);
for(i=0;i<=0xFF;i++)
{
outb(DACRG_DATA,(*(pal+3*i)/4));
outb(DACRG_DATA,(*(pal+3*i+1)/4));
outb(DACRG_DATA,(*(pal+3*i+2)/4));
}
}
void vga_setpalentry8(BYTE index, BYTE r, BYTE g, BYTE b)
{
outb(DACRG_WMADDR,index);
outb(DACRG_DATA,(r/4));
outb(DACRG_DATA,(g/4));
outb(DACRG_DATA,(b/4));
}
void vga_write_pixel1(unsigned x, unsigned y, unsigned c)
{
unsigned off, mask;
c = (c & 1) * 0xFF;
off = (vga_modes[vga_actmode].w / 8) * y + x / 8;
x = (x & 7) * 1;
mask = 0x80 >> x;
vpokeb(off, (vpeekb(off) & ~mask) | (c & mask));
}
void vga_write_pixel2(unsigned x, unsigned y, unsigned c)
{
unsigned off, mask;
c = (c & 3) * 0x55;
off = (vga_modes[vga_actmode].w * y + x) / 4;
x = (x & 3) * 2;
mask = 0xC0 >> x;
vpokeb(off, (vpeekb(off) & ~mask) | (c & mask));
}
void vga_write_pixel4p(unsigned x, unsigned y, unsigned c)
{
unsigned off, mask, p, pmask;
off = (vga_modes[vga_actmode].w / 8) * y + x / 8;
x = (x & 7) * 1;
mask = 0x80 >> x;
pmask = 1;
for(p = 0; p < 4; p++)
{
vga_set_plane(p);
if(pmask & c)
vpokeb(off, vpeekb(off) | mask);
else
vpokeb(off, vpeekb(off) & ~mask);
pmask <<= 1;
}
}
void vga_write_pixel8(unsigned x, unsigned y, unsigned c)
{
vpokeb(vga_modes[vga_actmode].w * vga_modes[vga_actmode].h + x, c);
}
void vga_write_pixel8x(unsigned x, unsigned y, unsigned c)
{
vga_set_plane(x & 3);
vpokeb((vga_modes[vga_actmode].w * vga_modes[vga_actmode].h + x )/ 4, c);
}
/*******************************
module init/fini functions
*******************************/
int vga_init()
{
vga_actmode = 2;
return 1;
}
void vga_fini()
{
}
/*******************************
module functions
*******************************/
VGAMODE vga_getmodeinfo(int mode)
{
return vga_modes[mode];
}
int vga_changemode(int mode)
{
vga_actmode = mode;
vga_write_regs(vga_modes[mode].initregs);
return 1;
}
void vga_setpalette(const unsigned char *palettearray)
{
void (*setpal)(const unsigned char*) = vga_modes[vga_actmode].setpal;
if( setpal )
setpal(palettearray);
}
void vga_setpalentry(BYTE index, BYTE r, BYTE g, BYTE b)
{
void (*setpalent)(BYTE,BYTE,BYTE,BYTE) = vga_modes[vga_actmode].setpalent;
if( setpalent )
setpalent(index, r, g, b);
}
void vga_putpixel(int x, int y, int color)
{
void (*putpixel)(int,int,int) = vga_modes[vga_actmode].putpixel;
if( putpixel )
putpixel(x,y,color);
}
void vga_line(int x1, int y1, int x2, int y2, int color)
{
int deltax = abs(x2 - x1);
int deltay = abs(y2 - y1);
int x = x1;
int y = y1;
int xinc1, xinc2;
int yinc1, yinc2;
int den, num, numadd, numpixels, curpixel;
if (x2 >= x1) // The x-values are increasing
{
xinc1 = 1;
xinc2 = 1;
}
else // The x-values are decreasing
{
xinc1 = -1;
xinc2 = -1;
}
if (y2 >= y1) // The y-values are increasing
{
yinc1 = 1;
yinc2 = 1;
}
else // The y-values are decreasing
{
yinc1 = -1;
yinc2 = -1;
}
if (deltax >= deltay) // There is at least one x-value for every y-value
{
xinc1 = 0; // Don't change the x when numerator >= denominator
yinc2 = 0; // Don't change the y for every iteration
den = deltax;
num = deltax / 2;
numadd = deltay;
numpixels = deltax; // There are more x-values than y-values
}
else // There is at least one y-value for every x-value
{
xinc2 = 0; // Don't change the x for every iteration
yinc1 = 0; // Don't change the y when numerator >= denominator
den = deltay;
num = deltay / 2;
numadd = deltax;
numpixels = deltay; // There are more y-values than x-values
}
for (curpixel = 0; curpixel <= numpixels; curpixel++)
{
vga_putpixel(x, y, color); // Draw the current pixel
num += numadd; // Increase the numerator by the top of the fraction
if (num >= den) // Check if numerator >= denominator
{
num -= den; // Calculate the new numerator value
x += xinc1; // Change the x as appropriate
y += yinc1; // Change the y as appropriate
}
x += xinc2; // Change the x as appropriate
y += yinc2; // Change the y as appropriate
}
}
void vga_rect(int x1, int y1, int x2, int y2, int color, int mode)
{
if( mode == VGA_RECT_FILL )
{
int i;
for( i=x1; i<=x2; i++ )
vga_line(i,y1,i,y2,color);
}
else
{
vga_line(x1,y1,x2,y1,color); // -
vga_line(x2,y1,x2,y2,color); // |
vga_line(x2,y2,x1,y2,color); // -
vga_line(x1,y2,x1,y1,color); // |
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -