"Fossies" - the Fresh Open Source Software Archive

Member "dosemu-1.4.0/src/env/video/miscemu.c" (4 May 2007, 9817 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 "miscemu.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  * Emulate miscellaneous registers for VGAEmu.
   12  * /REMARK
   13  *
   14  * DANG_END_MODULE
   15  *
   16  * DANG_BEGIN_CHANGELOG
   17  *
   18  * 1996/05/06:
   19  *  - Changed Misc_get_input_status_1() to get it _slower_.
   20  *    Idea from Adam D. Moss (aspirin@tigerden.com).
   21  *
   22  * 1996/05/09:
   23  *  - Added horizontal retrace too (--adm)
   24  *
   25  * 1998/01/05: Moved Misc_get_input_status_1() from attr.c into a separate
   26  * file (this one). Added emulation for the VGA regs which have their own
   27  * port addresses.
   28  * -- sw (Steffen Winterfeldt <wfeldt@suse.de>)
   29  *
   30  * DANG_END_CHANGELOG
   31  */
   32 
   33 
   34 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   35  * some configurable options
   36  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
   37 
   38 /*
   39  * Debug level for the Attribute Controller.
   40  * 0 - normal / 1 - useful / 2 - too much
   41  */
   42 #define DEBUG_MISC  0
   43 
   44 
   45 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
   46 #if !defined True
   47 #define False 0
   48 #define True 1
   49 #endif
   50 
   51 #define misc_msg(x...) v_printf("VGAEmu: " x)
   52 
   53 #if DEBUG_MISC >= 1
   54 #define misc_deb(x...) v_printf("VGAEmu: " x)
   55 #else
   56 #define misc_deb(x...)
   57 #endif
   58 
   59 #if DEBUG_MISC >= 2
   60 #define misc_deb2(x...) v_printf("VGAEmu: " x)
   61 #else
   62 #define misc_deb2(x...)
   63 #endif
   64 
   65 
   66 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
   67 #include "config.h"
   68 #include "emu.h"
   69 #include "vgaemu.h"
   70 #include "timers.h"
   71 
   72 
   73 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
   74 hitimer_t t_vretrace = 0;       /* cf. base/dev/misc/timers.c */
   75  
   76 
   77 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
   78 
   79 /*
   80  * DANG_BEGIN_FUNCTION Misc_init
   81  *
   82  * Initializes the Miscellaneous Output Register.
   83  * This function should be called during VGA mode initialization.
   84  * This is an interface function.
   85  *
   86  * DANG_END_FUNCTION
   87  *
   88  */
   89 void Misc_init()
   90 {
   91   unsigned char u;
   92 
   93   u = 0x23; /* CRTC port = 0x3d4, CPU access enabled */
   94 
   95   if(vga.VGA_mode == 7 || vga.VGA_mode == 15) {
   96     /* mono modes --> CRTC port = 0x3b4 */
   97     u &= ~1;
   98   }
   99 
  100   /* clock select */
  101   if(vga.VGA_mode >= 0) {
  102     if(vga.VGA_mode <= 3 || vga.VGA_mode == 7)
  103       u |= 4;   /* clock #1 */
  104     else if(vga.VGA_mode > 0x13)
  105       u |= 0xc; /* clock #3 */
  106   }
  107   else {
  108     u |= 0xc;   /* clock #3 */
  109   }
  110 
  111   /* # of lines, aka hsync/vsync polarity */
  112   if(vga.VGA_mode >= 0 && vga.VGA_mode <= 0x13) {
  113     switch(vga.VGA_mode) {
  114       case 0x0f:
  115       case 0x10: u |= 0x80; break;  /* 350 lines */
  116       case 0x11:
  117       case 0x12: u |= 0xc0; break;  /* 480 lines */
  118       default:   u |= 0x40; break;  /* 400 lines */
  119     }
  120   }
  121   else {
  122     u |= 0xc0;              /* 480 lines */
  123   }
  124 
  125   vga.misc.misc_output = u;
  126   vga.misc.feature_ctrl = 0;
  127 
  128   vga.config.mono_port = (vga.misc.misc_output & 1) ^ 1;
  129 
  130   if (vga.VGA_mode == 0x6)
  131     Misc_set_color_select(0x3f);
  132   else if (vga.VGA_mode <= 0x7)
  133     Misc_set_color_select(0x30);
  134 
  135   misc_msg("Misc_init done\n");
  136 }
  137 
  138 
  139 /*
  140  * DANG_BEGIN_FUNCTION Misc_set_misc_output
  141  *
  142  * Emulate Miscellaneous Output Register.
  143  * For now just stores the value.
  144  * This is a hardware emulation function.
  145  *
  146  * DANG_END_FUNCTION
  147  *
  148  */
  149 void Misc_set_misc_output(unsigned char data)
  150 {
  151   unsigned u;
  152 
  153   misc_deb2("Misc_set_misc_output: 0x%02x\n", (unsigned) data);
  154 
  155   vga.misc.misc_output = data;
  156 
  157   u = ~(vga.misc.misc_output & 1);
  158 
  159   u = (vga.misc.misc_output & 1) ^ 1;
  160 
  161   if(u != vga.config.mono_port) {
  162     vga.config.mono_port = u;
  163     misc_msg("Misc_set_misc_output: VGA changed to %s mode\n", u ? "mono" : "color");
  164     vgaemu_adj_cfg(CFG_MODE_CONTROL, 0);
  165   }
  166 }
  167 
  168 
  169 /*
  170  * DANG_BEGIN_FUNCTION Misc_set_color_select
  171  *
  172  * Emulate CGA color select Register 0x3d9.
  173  * This is a hardware emulation function.
  174  * Don't do background colors for now.
  175  *
  176  * DANG_END_FUNCTION
  177  *
  178  */
  179 void Misc_set_color_select(unsigned char data)
  180 {
  181   int i;
  182   int colors = 1 << vga.color_bits;
  183 
  184   misc_deb2("Misc_set_color_select: 0x%02x\n", (unsigned) data);
  185   if (vga.mode_class == TEXT) {
  186     /* border colour */
  187     vga.attr.data[0x11] = data & 0xf;
  188     vga.attr.dirty[0x11] = True;
  189   } else {
  190     if (colors == 2) {
  191       vga.attr.data[1] = data & 0xf;
  192     } else if (colors == 4) {
  193       if (data & 0x20) { /* cyan, magenta and white */
  194     vga.attr.data[1] = 3;
  195     vga.attr.data[2] = 5;
  196     vga.attr.data[3] = 7;
  197       } else { /* green, red and brown (yellow) */
  198     vga.attr.data[1] = 2;
  199     vga.attr.data[2] = 4;
  200     vga.attr.data[3] = 6;
  201       }
  202     } else {
  203       return;
  204     }
  205     vga.attr.data[0] = 0;
  206     for (i = 0; i < colors; i++) {
  207       vga.attr.dirty[i] = True;
  208       if ((data & 0x10) && i > 0) /* bright colors */
  209     vga.attr.data[i] |= 0x10;
  210     }
  211   }
  212 }
  213 
  214 /*
  215  * DANG_BEGIN_FUNCTION Misc_get_misc_output
  216  *
  217  * Emulate Miscellaneous Output Register.
  218  * This is a hardware emulation function.
  219  *
  220  * DANG_END_FUNCTION
  221  *
  222  */
  223 unsigned char Misc_get_misc_output()
  224 {
  225   misc_deb("Misc_get_misc_output: 0x%02x\n", (unsigned) vga.misc.misc_output);
  226 
  227   return vga.misc.misc_output;
  228 }
  229 
  230 
  231 /*
  232  * DANG_BEGIN_FUNCTION Misc_set_feature_ctrl
  233  *
  234  * Emulate Feature Control Register.
  235  * We just store the value.
  236  * This is a hardware emulation function.
  237  *
  238  * DANG_END_FUNCTION
  239  *
  240  */
  241 void Misc_set_feature_ctrl(unsigned char data)
  242 {
  243   misc_deb("Misc_set_feature_ctrl: 0x%02x\n", (unsigned) data);
  244 
  245   vga.misc.feature_ctrl = data;
  246 }
  247 
  248 
  249 /*
  250  * DANG_BEGIN_FUNCTION Misc_get_feature_ctrl
  251  *
  252  * Emulate Feature Control Register.
  253  * We simply return what was written into it by Misc_set_feature_ctrl().
  254  * This is a hardware emulation function.
  255  *
  256  * DANG_END_FUNCTION
  257  *
  258  */
  259 unsigned char Misc_get_feature_ctrl()
  260 {
  261   misc_deb("Misc_get_feature_ctrl: 0x%02x\n", (unsigned) vga.misc.feature_ctrl);
  262 
  263   return vga.misc.feature_ctrl;
  264 }
  265 
  266 
  267 /*
  268  * DANG_BEGIN_FUNCTION Misc_get_input_status_0
  269  *
  270  * Emulate Input Status #0 Register.
  271  * The only bit of (possible) interest could be bit 7 indicating an irq 2
  272  * due to vertical retrace.
  273  * But we don't do this, so we always return 0x00.
  274  * This is a hardware emulation function.
  275  *
  276  * DANG_END_FUNCTION
  277  *
  278  */
  279 unsigned char Misc_get_input_status_0()
  280 {
  281   unsigned char u = 0;
  282 
  283   misc_deb(
  284     "Misc_get_input_status_0: 0x%02x%s\n",
  285     (unsigned) u, u & 0x80 ? " (IRQ 2)" : ""
  286   );
  287 
  288   return u;
  289 }
  290 
  291 /*
  292  * DANG_BEGIN_FUNCTION Misc_get_input_status_1
  293  *
  294  * Emulate Input Status #1 Register.
  295  * The essential part is to simulate the retrace signals.
  296  * Clears the Attribute Controller's flip-flop.
  297  * This is a hardware emulation function.
  298  *
  299  * DANG_END_FUNCTION
  300  *
  301  */
  302 unsigned char Misc_get_input_status_1()
  303 {
  304   /* 
  305    * Graphic status - many programs will use this port to sync with
  306    * the vert & horz retrace so as not to cause CGA snow. On VGAs this
  307    * register is used to get full (read: fast) access to the video memory 
  308    * during the vertical retrace.
  309    *
  310    * bit 0 is Display Enable, bit 3 is Vertical Retrace
  311    * 00=display 01=horiz.retrace 09=vert.retrace
  312    * We're in vertical retrace?  If so, set VR and DE flags
  313    * We're in horizontal retrace?  If so, just set DE flag, 0 in VR
  314    *
  315    * Idea from Adam Moss:
  316    * Wait 20 milliseconds before we tell the DOS program that the VGA is
  317    * in a vertical retrace. This is to avoid that some programs run too
  318    * _fast_ in Dosemu (yes, I know, this sounds odd, but such programs
  319    * really exist!). This option works only if the system has
  320    * gettimeofday().
  321    *
  322    * Now simpler and more 'realtime', for better or for worse.  Implements
  323    * horizontal retrace too.  (--adm)
  324    *
  325    */
  326   static unsigned char hretrace = 0, vretrace = 0, first = 1;
  327   static hitimer_t t_vretrace = 0;
  328   static int flip = 0;
  329   /* Timings are 'ballpark' guesses and may vary from mode to mode, but
  330      such accuracy is probably not important... I hope. (--adm) */
  331   static int vvfreq = 17000;    /* 70 Hz - but the best we'll get with
  332                  * current PIC will be 50 Hz */
  333   hitimer_t t, tdiff;
  334   unsigned char retval;
  335 
  336   vga.attr.flipflop = 0;        /* ATTR_INDEX_FLIPFLOP */
  337 
  338 #ifdef OLD_CGA_SNOW_CODE
  339   /* old 'cga snow' code with the new variables - looks terrible,
  340    * but since it sometimes works we keep it for emergencies */
  341   hretrace ^= 0x01; vretrace++;
  342   retval = 0xc6 | hretrace | (vretrace & 0xfc ? 0 : 0x09);
  343 #else
  344   t = GETusTIME(0);
  345 
  346   if(first) { t_vretrace = t; first = 0; }
  347   tdiff = t - t_vretrace;
  348 
  349 #if DEBUG_MISC >= 2
  350   r_printf("VGAEmu: Misc: VR diff = %ld\n", tdiff);
  351 #endif
  352 
  353   if(vretrace) {
  354     /* We're in 'display' mode and should return 0 in DE and VR */
  355     /* set display after 1ms from retrace start */
  356     if(tdiff > 1000) vretrace = hretrace = 0;
  357   }
  358   else {
  359     /* set retrace on timeout */
  360     if(tdiff > vvfreq) {
  361       /* We're in vertical retrace?  If so, set VR and DE flags */
  362       vretrace = 0x09; t_vretrace = t;
  363     }
  364     else {
  365       /* The timer can't be relied upon for the very short intervals necessary
  366      for horizontal retrace emulation
  367      (such as the old "hretrace = (tdiff%49) > 35;").
  368      The following is a crude switch-on switch-off approach after
  369      10 reads taken from DosBox. It seems to work in most cases,
  370          (in particular Commander Keen 4) */
  371       flip++;
  372       if (flip > 20) flip = 0;
  373       /* We're in horizontal retrace?  If so, just set DE flag, 0 in VR */
  374       hretrace = flip > 10;
  375     }
  376   }
  377 
  378   retval = 0xc4 | hretrace | vretrace;
  379 
  380   /*
  381    * Hercules cards use bit 7 for vertical retrace. This bit is not used
  382    * by VGA cards, so there should be no conflict here. -- sw
  383    */
  384   if(vga.config.mono_port && vretrace) retval &= ~0x80;
  385 
  386 #endif  /* OLD_CGA_SNOW_CODE */
  387 
  388   misc_deb(
  389     "Misc_get_input_status_1: 0x%02x%s\n",
  390     (unsigned) retval,
  391     vretrace ? " (V_RETRACE)" : hretrace ? " (H_RETRACE)" : ""
  392   );
  393 
  394   return retval;
  395 }
  396