📄 tl_vga.c
字号:
if( hblnk_end > pReg[H_TOTAL_INDEX].value) hblnk_end = pReg[H_TOTAL_INDEX].value; /* write horizontal blanking - include 7th test bit (always 1) */ pReg[H_BLANKING_END_INDEX].value = (hblnk_end & 0x1f) | 0x80; /* include the 5th bit of the horizontal blanking in the horizontal retrace reg. */ hrt_end = ((hrt_end & 0x1f) | ((hblnk_end & 0x20) << 2)); pReg[H_RETRACE_END_INDEX].value = hrt_end; /* get the vt retrace */ vrt_start = pReg[V_RETRACE_START_INDEX].value | ((pReg[OVERFLOW_INDEX].value & 0x04) << 6) | ((pReg[OVERFLOW_INDEX].value & 0x80) << 2); /* set the new retrace start */ vrt_start += center_y; /* check it's legal, get the display line count */ vert_display = (pReg[V_END_INDEX].value | ((pReg[OVERFLOW_INDEX].value & 0x02) << 7) | ((pReg[OVERFLOW_INDEX].value & 0x40) << 3)) + 1; if (vrt_start < vert_display) vrt_start = vert_display; /* and get the vertical line count */ vert_total = pReg[V_TOTAL_INDEX].value | ((pReg[OVERFLOW_INDEX].value & 0x01) << 8) | ((pReg[OVERFLOW_INDEX].value & 0x20) << 4); pReg[V_RETRACE_START_INDEX].value = (vrt_start & 0xff); pReg[OVERFLOW_INDEX].value &= ~0x84; pReg[OVERFLOW_INDEX].value |= ((vrt_start & 0x100) >> 6); pReg[OVERFLOW_INDEX].value |= ((vrt_start & 0x200) >> 2); vrt_end = vrt_start + vrt; if (vrt_end > vert_total) vrt_end = vert_total; /* write retrace end, include CRT protection and IRQ2 bits */ pReg[V_RETRACE_END_INDEX].value = (vrt_end & 0x0f) | 0x80 | 0x20; /* get the start of vt blanking */ vblnk_start = vert_display + 1; /* check it's legal */ if (vblnk_start > vrt_start) vblnk_start = vrt_start; /* and the end */ vblnk_end = vrt_end + 2; /* check it's legal */ if (vblnk_end > vert_total) vblnk_end = vert_total; /* set vblank start */ pReg[V_BLANKING_START_INDEX].value = (vblnk_start & 0xff); /* write out any overflows */ pReg[OVERFLOW_INDEX].value &= ~0x08; pReg[OVERFLOW_INDEX].value |= ((vblnk_start & 0x100) >> 5); pReg[MAXIMUM_SCANLINE_INDEX].value &= ~0x20; pReg[MAXIMUM_SCANLINE_INDEX].value |= ((vblnk_start &0x200) >> 4); /* set the vblank end */ pReg[V_BLANKING_END_INDEX].value = (vblnk_end & 0xff);}/* Set a VGA mode */static void vga_setvgamode(uint8 mode){ __dpmi_regs r; r.x.ax = mode; __dpmi_int(0x10, &r);}static void vga_set_overscan(int index){ outportb(VGA_ATTR, 0x31); outportb(VGA_ATTR, index);}static void vga_outregs(vgareg_t *reg){ uint8 crtc_val; /* Disable interrupts, wait for vertical retrace */// thin_vga_waitvsync(); THIN_DISABLE_INTS(); /* Sequencer reset */ outportb(VGA_SEQ_ADDR, 0x00); outportb(VGA_SEQ_DATA, 0x01); crtc_val = inportb(VGA_CRTC_DATA) & 0x7F; /* Unprotect registers 0-7 */ outportb(VGA_CRTC_ADDR, 0x11); outportb(VGA_CRTC_DATA, crtc_val); /* Reset read/write flip-flop */ inportb(VGA_STATUS); /* Do the icky register stuff */ while (reg->port) { switch(reg->port) { case VGA_ATTR: /* Reset read/write flip-flop */ inportb(VGA_STATUS); /* Ensure VGA output is enabled - bit 5 */ outportb(VGA_ATTR, reg->index | 0x20); outportb(VGA_ATTR, reg->value); break; case VGA_MISC: /* Write directly to port */ outportb(reg->port, reg->value); break; case VGA_SEQ_ADDR: case VGA_CRTC_ADDR: default: /* Index to port, value to port + 1 */ outportb(reg->port, reg->index); outportb(reg->port + 1, reg->value); break; } reg++; } /* Set overscan color */ vga_set_overscan(DEFAULT_OVERSCAN); /* Clear sequencer reset */ outportb(VGA_SEQ_ADDR, 0x00); outportb(VGA_SEQ_DATA, 0x03); THIN_ENABLE_INTS();}static int vga_getregsize(vgareg_t *regs){ int reg_size = 0; while (regs->port) { reg_size++; regs++; } return reg_size;}void thin_vga_scanlines(bool scanlines_on){ vgareg_t *reg; if (NULL == vga_mode) return; /* modify (or not) for scanlines */ if (true == scanlines_on) reg = tweak_addscanlines(vga_mode->regs, vga_getregsize(vga_mode->regs)); else reg = vga_mode->regs; /* center the screen */ if (vga_getregsize(vga_mode->regs) > 1) tweak_centermode(reg); /* send them to the VGA controller */ vga_outregs(reg);}/* Set up VGA mode 13h, then tweak it appropriately */int thin_vga_setmode(int width, int height, int bpp){ if (8 != bpp) return -1; vga_mode = vidmodes; /* Search for the video mode */ while ((vga_mode->width != width) || (vga_mode->height != height)) { if (NULL == vga_mode->regs) { vga_mode = NULL; return -1; } vga_mode++; } /* Set up our standard mode 13h */ vga_setvgamode(MODE_13H); /* modify the register values, and send 'em out */ thin_vga_scanlines(false); return 0;}/* Destroy VGA */void thin_vga_shutdown(void){ /* set textmode */ vga_setvgamode(MODE_TEXT); thin_bmp_destroy(&screen); if (0 == thinlib_nearptr) thin_bmp_destroy(&hardware);}/* Initialize VGA */int thin_vga_init(int width, int height, int bpp){ if (8 != bpp) return -1; if (thinlib_nearptr) { screen = thin_bmp_createhw((uint8 *) THIN_PHYS_ADDR(0xA0000), width, height, bpp, width); if (NULL == screen) return -1; } else { hardware = thin_bmp_createhw((uint8 *) 0xA0000, width, height, bpp, width); if (NULL == hardware) return -1; screen = thin_bmp_create(width, height, bpp, 0); if (NULL == screen) return -1; } /* Set the initial video mode, no scanlines */ if (thin_vga_setmode(width, height, bpp)) { thin_vga_shutdown(); return -1; } return 0;}/* cram an 8-bit, 256 entry rgb palette into 6-bit vga */void thin_vga_setpalette(rgb_t *palette, int index, int length){ int i; /* we also want to find the closest color index to black, ** and set that as our overscan color */ int overscan_index = 0; rgb_t overscan = { 255, 255, 255 }; outportb(VGA_PAL_WRITE, index); for (i = 0; i < length; i++) { if (palette[i].r <= overscan.r && palette[i].g <= overscan.g && palette[i].b <= overscan.b) { overscan = palette[i]; overscan_index = index + i; } outportb(VGA_PAL_DATA, palette[i].r >> 2); outportb(VGA_PAL_DATA, palette[i].g >> 2); outportb(VGA_PAL_DATA, palette[i].b >> 2); } vga_set_overscan(overscan_index);}void thin_vga_waitvsync(void){ while (0 == (inportb(VGA_STATUS) & 0x08)); //while (inportb(VGA_STATUS) & 0x08);}bitmap_t *thin_vga_lockwrite(void){ /* always return screen */ return screen;}void thin_vga_freewrite(int num_dirties, rect_t *dirty_rects){ UNUSED(num_dirties); UNUSED(dirty_rects); if (0 == thinlib_nearptr) { dosmemput(screen->line[0], hardware->pitch * hardware->height, (int) hardware->line[0]); }}/*** $Log: tl_vga.c,v $** Revision 1.9 2001/03/12 06:06:55 matt** better keyboard driver, support for bit depths other than 8bpp**** Revision 1.8 2001/02/01 06:28:26 matt** thinlib now works under NT/2000**** Revision 1.7 2001/01/15 05:25:52 matt** i hate near pointers**** Revision 1.6 2000/12/16 21:18:11 matt** thinlib cleanups**** Revision 1.5 2000/12/16 17:30:15 matt** handle overscan more elegantly**** Revision 1.4 2000/11/25 20:28:34 matt** moved verboseness into correct places**** Revision 1.3 2000/11/06 02:22:33 matt** generalized video driver (tl_video.c)**** Revision 1.2 2000/11/05 16:32:36 matt** thinlib round 2**** Revision 1.1 2000/11/05 06:29:03 matt** initial revision***/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -