"Fossies" - the Fresh Open Source Software Archive

Member "dosemu-1.4.0/src/env/video/crtcemu.c" (4 May 2007, 11255 Bytes) of package /linux/misc/old/dosemu-1.4.0.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "crtcemu.c" see the Fossies "Dox" file reference documentation.

    1 /* 
    2  * (C) Copyright 1992, ..., 2007 the "DOSEMU-Development-Team".
    3  *
    4  * for details see file COPYING.DOSEMU in the DOSEMU distribution
    5  */
    6 
    7 /*
    8  * DANG_BEGIN_MODULE
    9  *
   10  * REMARK
   11  * The VGA CRT Controller emulator for VGAEmu.
   12  * /REMARK
   13  * DANG_END_MODULE
   14  *
   15  * DANG_BEGIN_CHANGELOG
   16  *
   17  * 1999/01/05: Correct initial values for standard VGA modes.
   18  * -- sw (Steffen Winterfeldt <wfeldt@suse.de>)
   19  *
   20  * DANG_END_CHANGELOG
   21  *
   22  */
   23 
   24 
   25 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   26  * some configurable options
   27  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
   28 
   29 /*
   30  * Debug level for the CRT Controller.
   31  * 0 - normal / 1 - useful / 2 - too much
   32  */
   33 #define DEBUG_CRTC  0
   34 
   35 
   36 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
   37 #if !defined True
   38 #define False 0
   39 #define True 1
   40 #endif
   41 
   42 #define crtc_msg(x...) v_printf("VGAEmu: " x)
   43 
   44 #if DEBUG_CRTC >= 1
   45 #define crtc_deb(x...) v_printf("VGAEmu: " x)
   46 #else
   47 #define crtc_deb(x...)
   48 #endif
   49 
   50 #if DEBUG_CRTC >= 2
   51 #define crtc_deb2(x...) v_printf("VGAEmu: " x)
   52 #else
   53 #define crtc_deb2(x...)
   54 #endif
   55 
   56 
   57 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
   58 #include "config.h"
   59 #include "emu.h"
   60 #include "vgaemu.h"
   61 #include "video.h"
   62 #include "memory.h"
   63 
   64 
   65 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
   66 static unsigned char crtc_ival[16][CRTC_MAX_INDEX + 1] = {
   67   {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, 0xff},
   68   {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, 0xff},
   69   {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, 0xff},
   70   {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, 0xff},
   71   {0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, 0xff},
   72   {0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, 0xff},
   73   {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2, 0xff},
   74   {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, 0xff},
   75 
   76   {0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3, 0xff},
   77   {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3, 0xff},
   78   {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, 0xff},
   79   {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, 0xff},
   80   {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xc3, 0xff},
   81   {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, 0xff},
   82   {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3, 0xff},
   83   {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, 0xff}
   84 };
   85 
   86 
   87 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
   88 
   89 /*
   90  * DANG_BEGIN_FUNCTION CRTC_init
   91  *
   92  * Initializes the CRT Controller.
   93  * This is an interface function.
   94  *
   95  * DANG_END_FUNCTION
   96  *
   97  */
   98 void CRTC_init()
   99 {
  100   unsigned i, j = 15;
  101 
  102   if(vga.VGA_mode >= 0 && vga.VGA_mode <= 7)
  103     j = vga.VGA_mode;
  104   else if(vga.VGA_mode >= 0x0d && vga.VGA_mode <= 0x13)
  105     j = vga.VGA_mode - 5;
  106 
  107   for(i = 0; i <= CRTC_MAX_INDEX; i++) vga.crtc.data[i] = crtc_ival[j][i];
  108 
  109   vga.crtc.index = 0;
  110   vga.crtc.readonly = 1;
  111 
  112   if(j == 15) {
  113     /* adjust crtc values for vesa modes that fit certain conditions */
  114     if (vga.width < 2048 && vga.width % vga.char_width == 0)
  115       vga.crtc.data[0x1] = vga.crtc.data[0x2] =
  116     vga.width / vga.char_width - 1;
  117     if (vga.height <= 1024) {
  118       int h = vga.height - 1;
  119       vga.crtc.data[0x12] = vga.crtc.data[0x15] = h & 0xff;
  120       vga.crtc.data[0x7] &= ~0x4a;
  121       vga.crtc.data[0x7] |= ((h & 0x100) >> (8 - 1))|((h & 0x200) >> (9 - 6))|
  122     (h & 0x100) >> (8 - 3);
  123       vga.crtc.data[0x9] &= ~0x20;
  124       vga.crtc.data[0x9] |= (h & 0x200) >> (9 - 5);
  125     }
  126     if (vga.scan_len < 2048 && vga.color_bits == 8) {
  127       vga.crtc.data[0x13] = vga.scan_len / 8;
  128       vga.crtc.data[0x14] = 0x40;
  129     } else if (vga.scan_len < 1024 && vga.mode_class == TEXT) {
  130       vga.crtc.data[0x13] = vga.scan_len / 4;
  131       vga.crtc.data[0x17] = 0xa3;
  132     } else if (vga.scan_len < 512) { /* 4 bpp */
  133       vga.crtc.data[0x13] = vga.scan_len / 2;
  134     }
  135   }
  136 
  137   vgaemu_adj_cfg(CFG_CRTC_ADDR_MODE, 1);
  138   vgaemu_adj_cfg(CFG_CRTC_WIDTH, 1);
  139   vgaemu_adj_cfg(CFG_CRTC_HEIGHT, 1);
  140   vgaemu_adj_cfg(CFG_CRTC_LINE_COMPARE, 1);
  141 #if 0
  142   /* need to fix vgaemu before this is possible */
  143   vgaemu_adj_cfg(CFG_MODE_CONTROL, 1);
  144 #endif
  145   
  146   crtc_msg("CRTC_init done\n");
  147 }
  148 
  149 
  150 void CRTC_set_index(unsigned char index)
  151 {
  152   crtc_deb2(
  153     "CRTC_set_index: 0x%02x%s\n",
  154     (unsigned) index,
  155     index > CRTC_MAX_INDEX ? " (too large)" : ""
  156   );
  157 
  158   vga.crtc.index = index;
  159 }
  160 
  161 
  162 unsigned char CRTC_get_index()
  163 {
  164   crtc_deb2("CRTC_get_index: 0x%02x\n", (unsigned) vga.crtc.index);
  165 
  166   return vga.crtc.index;
  167 }
  168 
  169 
  170 void CRTC_write_value(unsigned char data)
  171 {
  172 #define NEWBITS(a) (delta & (a))
  173   unsigned u = data, u1, delta, ind = vga.crtc.index;
  174 
  175   if(ind > CRTC_MAX_INDEX) {
  176     crtc_deb("CRTC_write_value: data (0x%02x) ignored\n", u);
  177     return;
  178   }
  179 
  180   crtc_deb2("CRTC_write_value: crtc[0x%02x] = 0x%02x\n", ind, u);
  181 
  182   if(vga.crtc.readonly) {
  183     /* read only regs 00h-07h with the exception of bit4 in 07h */
  184     if (ind <= 6)
  185       return;
  186     if (ind == 7)
  187       data = (vga.crtc.data[ind] & 0xef) | (data & 0x10);
  188   }
  189 
  190   delta = vga.crtc.data[ind] ^ data;
  191   if(!delta) return;
  192   vga.crtc.data[ind] = data;
  193 
  194   switch(ind) {
  195     case 0x00:
  196     case 0x01:
  197     case 0x02:
  198     case 0x03:
  199     case 0x04:
  200     case 0x05:
  201       if(NEWBITS(0xFF)) {
  202     vgaemu_adj_cfg(CFG_CRTC_WIDTH, 0);
  203       }
  204       crtc_deb("CRTC_write_value: crtc[0x%02x] = 0x%02x (guessed)\n", ind, u);
  205       break;
  206 
  207     case 0x06:
  208       if(NEWBITS(0xFF)) {
  209     vgaemu_adj_cfg(CFG_CRTC_HEIGHT, 0);
  210       }
  211       crtc_deb("CRTC_write_value: crtc[0x%02x] = 0x%02x (guessed)\n", ind, u);
  212       break;
  213 
  214     case 0x07:
  215       if(NEWBITS(0x10)) {
  216     vgaemu_adj_cfg(CFG_CRTC_LINE_COMPARE, 0);
  217       }
  218       if(NEWBITS(0xEF)) {
  219     vgaemu_adj_cfg(CFG_CRTC_HEIGHT, 0);
  220       }
  221       crtc_deb("CRTC_write_value: crtc[0x%02x] = 0x%02x (guessed)\n", ind, u);
  222       break;
  223 
  224     case 0x09:
  225       if(NEWBITS(0x40)) {
  226     vgaemu_adj_cfg(CFG_CRTC_LINE_COMPARE, 0);
  227       }
  228       if(NEWBITS(0xBF)) {
  229     vgaemu_adj_cfg(CFG_CRTC_HEIGHT, 0);
  230       }
  231       crtc_deb("CRTC_write_value: crtc[0x%02x] = 0x%02x (guessed)\n", ind, u);
  232       break; 
  233      
  234     case 0x0a:          /* cursor shape start */
  235       CURSOR_START(vga.crtc.cursor_shape) = u;
  236       crtc_deb("CRTC_write_value: cursor shape start = 0x%02x\n", u);
  237       break; 
  238      
  239     case 0x0b:          /* cursor shape end   */
  240       CURSOR_END(vga.crtc.cursor_shape) = u;
  241       crtc_deb("CRTC_write_value: cursor shape end = 0x%02x\n", u);
  242       break; 
  243      
  244     case 0x0c:      /* Start Address High */
  245       /* these shifts involving vga.crtc.addr_mode should really be rotations, 
  246          depending on mode control bit 5 */
  247       vga.display_start = (vga.crtc.data[0x0d] + (u << 8)) << vga.crtc.addr_mode;
  248       crtc_deb("CRTC_write_value: Start Address = 0x%04x, high changed\n", vga.display_start);
  249       break;
  250 
  251     case 0x0d:      /* Start Address Low */
  252       vga.display_start = (u + (vga.crtc.data[0x0c] << 8)) << vga.crtc.addr_mode;
  253       /* this shift should really be a rotation, depending on mode control bit 5 */
  254       crtc_deb("CRTC_write_value: Start Address = 0x%04x, low changed\n", vga.display_start);
  255       break;
  256 
  257     case 0x0e:      /* Cursor Location High */
  258       vga.crtc.cursor_location = (vga.crtc.data[0x0f] + (u << 8)) << vga.crtc.addr_mode; 
  259       crtc_deb("CRTC_write_value: Cursor Location = 0x%04x\n", vga.crtc.cursor_location);
  260       break;
  261 
  262     case 0x0f:      /* Cursor Location  Low */
  263       vga.crtc.cursor_location = (u + (vga.crtc.data[0x0e] << 8)) << vga.crtc.addr_mode;
  264       crtc_deb("CRTC_write_value: Cursor Location = 0x%04x\n", vga.crtc.cursor_location);
  265       break;
  266 
  267     case 0x11:
  268       if(NEWBITS(0x80)) {
  269         vga.crtc.readonly = (data >= 0x80);
  270       }
  271       if(NEWBITS(0x7F)) {
  272     vgaemu_adj_cfg(CFG_CRTC_HEIGHT, 0);
  273       }
  274       crtc_deb("CRTC_write_value: crtc[0x%02x] = 0x%02x (guessed)\n", ind, u);
  275       break;
  276 
  277     case 0x10:
  278     case 0x12:
  279       if(NEWBITS(0xFF)) {
  280     vgaemu_adj_cfg(CFG_CRTC_HEIGHT, 0);
  281       }
  282       crtc_deb("CRTC_write_value: crtc[0x%02x] = 0x%02x (guessed)\n", ind, u);
  283       break;
  284   
  285     case 0x13:          /* Number of bytes in a scanline */
  286       if(NEWBITS(0xFF)) {
  287     vgaemu_adj_cfg(CFG_CRTC_ADDR_MODE, 0);
  288       }
  289       crtc_deb("CRTC_write_value: crtc[0x%02x] = 0x%02x (guessed)\n", ind, u);
  290       break;
  291 
  292     case 0x14:      /* Underline Location */
  293       if(NEWBITS(0x40)) {
  294     vgaemu_adj_cfg(CFG_CRTC_ADDR_MODE, 0);
  295       }
  296       break;
  297 
  298     case 0x15:
  299     case 0x16:
  300       if(NEWBITS(0xFF)) {
  301     vgaemu_adj_cfg(CFG_CRTC_HEIGHT, 0);
  302       }
  303       crtc_deb("CRTC_write_value: crtc[0x%02x] = 0x%02x (guessed)\n", ind, u);
  304       break;
  305 
  306     case 0x17:      /* Mode Control */
  307       if(NEWBITS(0x03)) {
  308     crtc_deb("CRTC_write_value: crtc[0x%02x] = 0x%02x (guessed)\n", ind, u);
  309     vgaemu_adj_cfg(CFG_MODE_CONTROL, 0);
  310       }
  311       if(NEWBITS(0x40)) {
  312     vgaemu_adj_cfg(CFG_CRTC_ADDR_MODE, 0);
  313       }
  314       if(NEWBITS(0x80)) {
  315         crtc_deb("CRTC_write_value: %svideo access\n", (data & 0x80) ? "" : "no ");
  316 
  317         u1 = vga.config.video_off;
  318         vga.config.video_off = (vga.config.video_off & ~4) + (((data >> 5) & 4) ^ 4);
  319         if(u1 != vga.config.video_off) {
  320           crtc_deb("CRTC_write_value: video signal turned %s\n", vga.config.video_off ? "off" : "on");
  321         }
  322       }
  323       break;
  324 
  325     case 0x18: /* line compare */
  326       if(NEWBITS(0xFF)) {
  327     vgaemu_adj_cfg(CFG_CRTC_LINE_COMPARE, 0);
  328       }
  329       break;
  330       
  331     default:
  332       crtc_deb("CRTC_write_value: crtc[0x%02x] = 0x%02x (ignored)\n", ind, u);
  333   }
  334 }
  335 
  336 
  337 unsigned char CRTC_read_value()
  338 {
  339   unsigned char uc;
  340 
  341   uc = vga.crtc.index > CRTC_MAX_INDEX ? 0x00 : vga.crtc.data[vga.crtc.index];
  342 
  343   crtc_deb2("CRTC_read_value: crtc[0x%02x] = 0x%02x\n", (unsigned) vga.crtc.index, (unsigned) uc);
  344 
  345   return uc;
  346 }
  347