⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tl_vga.c

📁 这是模拟器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
   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 + -