5. 以上这些知识从哪些书籍上可以获得?
INT 10,0 - Set Video Mode
AH = 00
AL = 00 40x25 B/W text (CGA,EGA,MCGA,VGA)
= 01 40x25 16 color text (CGA,EGA,MCGA,VGA)
= 02 80x25 16 shades of gray text (CGA,EGA,MCGA,VGA)
= 03 80x25 16 color text (CGA,EGA,MCGA,VGA)
= 04 320x200 4 color graphics (CGA,EGA,MCGA,VGA)
= 05 320x200 4 color graphics (CGA,EGA,MCGA,VGA)
= 06 640x200 B/W graphics (CGA,EGA,MCGA,VGA)
= 07 80x25 Monochrome text (MDA,HERC,EGA,VGA)
= 08 160x200 16 color graphics (PCjr)
= 09 320x200 16 color graphics (PCjr)
= 0A 640x200 4 color graphics (PCjr)
= 0B Reserved (EGA BIOS function 11)
= 0C Reserved (EGA BIOS function 11)
= 0D 320x200 16 color graphics (EGA,VGA)
= 0E 640x200 16 color graphics (EGA,VGA)
= 0F 640x350 Monochrome graphics (EGA,VGA)
= 10 640x350 16 color graphics (EGA or VGA with 128K)
640x350 4 color graphics (64K EGA)
= 11 640x480 B/W graphics (MCGA,VGA)
= 12 640x480 16 color graphics (VGA)
= 13 320x200 256 color graphics (MCGA,VGA)
= 8x EGA, MCGA or VGA ignore bit 7, see below
= 9x EGA, MCGA or VGA ignore bit 7, see below
- if AL bit 7=1, prevents EGA,MCGA & VGA from clearing display
- function updates byte at 40:49; bit 7 of byte 40:87
(EGA/VGA Display Data Area) is set to the value of AL bit 7
// enter standard graphic mode
int display_enter_graph(int mode)
{
short hr = 0;
union REGS r;
memset(&r, 0, sizeof(r));
if (mode < 0x100) {
r.w.ax = (short)mode;
int386(0x10, &r, &r);
r.h.ah = 0xf;
int386(0x10, &r, &r);
if (r.h.al != mode) hr = -1;
}
else {
r.w.ax = 0x4f02;
r.w.bx = (short)mode;
int386(0x10, &r, &r);
if (r.w.ax != 0x004f) hr = -1;
}
return hr;
}
debug
mov ax, 13 ; 设置 ah=0(0号函数上面有说明), al=0x13(0x13模式,320x200)
int 10 ; 调用显卡中断
int 20 ; DOS命令:退出程序
-e a000:0000
void putpixel(int x, int y, unsigned char color)
{
static unsigned char far *videobuf = (unsigned char far*)0xa0000000;
if (x >= 0 && y >= 0 && x < 320 && y < 200) {
videobuf[y * 320 + x] = color;
}
}
void putpixel(int x, int y, unsigned char color)
{
static unsigned char far *videobuf = (unsigned char far*)0xa0000000;
if (((unsigned)x) < 320 && ((unsigned)y) < 200) {
videobuf[(y << 6) + (unsigned)(y << 8) + x] = color;
}
}
mov edx, 0x03c7
mov al, color
out dx, al
inc dx
mov al, R
out dx, al
mov al, G
out dx, al
mov al, B
out dx, al
void display_set_palette(unsigned char color, char r, char g, char b)
{
short port = 0x03c8;
outp(port, color);
port++;
outp(port, r);
outp(port, g);
outp(port, b);
}
outpw(0x3C4, 0x0100); /* synchronous reset */
outp(0x3D4, 0x11); /* enable crtc regs 0-7 */
outp(0x3D5, inp(0x3D5) & 0x7F);
outpw(0x3C4, 0x0604); /* disable chain-4 */
for (reg=mode->regs; reg->port; reg++) { /* set the VGA registers */
if (reg->port == 0x3C0) {
inp(0x3DA);
outp(0x3C0, reg->index | 0x20);
outp(0x3C0, reg->value);
}
else if (reg->port == 0x3C2) {
outp(reg->port, reg->value);
}
else {
outp(reg->port, reg->index);
outp(reg->port + 1, reg->value);
}
}
if (mode->hrs) {
outp(0x3D4, 0x11); outp(0x3D5, inp(0x3D5) & 0x7F);
outp(0x3D4, 0x04); outp(0x3D5, inp(0x3D5) + mode->hrs);
outp(0x3D4, 0x11); outp(0x3D5, inp(0x3D5) | 0x80);
}
if (mode->shift) {
outp(0x3CE, 0x05);
outp(0x3CF, (inp(0x3CF) & 0x60) | 0x40);
inp(0x3DA);
outp(0x3C0, 0x30);
outp(0x3C0, inp(0x3C1) | 0x40);
for (c=0; c<16; c++) {
outp(0x3C0, c);
outp(0x3C0, c);
}
outp(0x3C0, 0x20);
}
if (mode->repeat) {
outp(0x3D4, 0x09);
outp(0x3D5, (inp(0x3D5) & 0x60) | mode->repeat);
}
outp(0x3D4, 0x13); /* set scanline length */
outp(0x3D5, width / 8);
outpw(0x3C4, 0x0300); /* restart sequencer */
int display_vesa_switch(int window, int bank)
{
union REGS r;
r.x.eax = 0x4f05;
r.x.ebx = window;
r.x.edx = bank;
int386(0x10, &r, &r);
return 0;
}
int display_trident_switch(unsigned char bank)
{
outp(0x3c4, 0x0e);
outp(0x3c5, bank ^ 0x2);
return 0;
}
//---------------------------------------------------------------------
// Framebuffer Access
//---------------------------------------------------------------------
// copy rect from memory to video frame buffer
void display_bits_set(int sx, int sy, const void *src, long pitch,
int x, int y, int w, int h);
// get rect from frame buffer to memory
void display_bits_get(int sx, int sy, void *dst, long pitch,
int x, int y, int w, int h);
// write row to video frame buffer
void display_row_write(int x, int y, const void *buffer, int npixels);
// read row from video frame buffer
void display_row_read(int x, int y, void *buffer, int npixels);
from: https://www.zhihu.com/question/20722310#answer-37937615