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

📄 combi.c

📁 一款DOS下的RAM disk和disk cache组合在一起的工具。
💻 C
字号:
/*
 *  This program is copyright (C) 1992 by Vadim V. Vlasov, Moscow, Russia.
 *
 * The source is supplied as an example of interface to COMBI-disk (C)
 * device driver. You may change the source as You wish, however I'm not
 * responsible for the results of Your changes.
 *
 * The program is written for MS C 6.0 and may be compiled in TINY or
 * SMALL memory model.
 *
 * If You don't have ANSI.SYS installed or want to redirect output to a file
 * You may define NO_ANSI and recompile the program.
 *
 */


#include <stdio.h>
#include <string.h>
#include <dos.h>
#include "ioctl.h"    /* definitions of structures and control codes */

#ifndef  NO_ANSI
#define  bold(string)        "\x1b[1m"#string"\x1b[0m"
#define  red_bold(string)    "\x1b[1;31m"#string"\x1b[0m"
#define  yellow_bold(string) "\x1b[1;33m"#string"\x1b[0m"
#define  cyan_bold(string)   "\x1b[1;36m"#string"\x1b[0m"
#else
#define  bold(string)        #string
#define  red_bold(string)    #string
#define  yellow_bold(string) #string
#define  cyan_bold(string)   #string
#endif

main(int argc, char *argv[])
{
  struct combi_status cmb_st;
  char   choice, drive=2;
  union  REGS  r;
  void far * ptr;
  int i,j;
  char   *chpt, optchar;
  char   oldopt, opt;

/*
 * Scan all drives and try to read IOCtl packet of length sizeof(cmb_st).
 * If successful then probably that drive is COMBI's RAM disk. To ensure
 * this we check that first 6 bytes of returned packet are "COMBI\0".
 */

  do {
    drive++;
    r.x.ax=0x4404;
    r.h.bl=drive;
    r.x.cx=sizeof(cmb_st);
    r.x.dx=(unsigned)&cmb_st;
  } while (((intdos(&r,&r)!=sizeof(cmb_st))||
           (r.x.cflag & 0x1)||
           strcmp(cmb_st.ID_name,"COMBI"))&&(drive < 16));

  if(drive >= 16) {
    printf(red_bold(Error: COMBI-disk not installed!(?)) "\n");
    exit(1);
  }

  printf("\t" yellow_bold(COMBI-disk version %1d.%02d installed as drive %c:) "\n",
          cmb_st.version >> 8, cmb_st.version & 0xff, drive+'A'-1);

  if(argc > 1) {
    optchar = '\0';
    oldopt = opt = cmb_st.COMBI_options;

    for(i=1; i < argc; i++) {   /* Scan all command line arguments. */

      strlwr(argv[i]);
      if(isdigit(*argv[i]) || *argv[i]=='-' || *argv[i]=='+') {

        /* If an argument is a number then try to reallocate COMBI's
         * memory size.*/

        j = atoi(argv[i]);
        if(change_mem(drive, cmb_st.version, j))
          printf(red_bold(Can\'t reallocate memory!) "\a\n");
        else
          printf("Memory reallocated by %dK. ", j);
      } else {
        optchar = *argv[i];
        chpt = argv[i]+1;
        while(optchar) {
          switch(optchar) {
            case 'n':
            /* Option 'n' - ignore (or not ignore if 'n-')
             * 'sector not found error'. */
              if(*chpt == '-') {
                opt &= ~OPT_NO_SNF;   /* Reset the option bit */
                chpt++;
              } else {
                opt |= OPT_NO_SNF;    /* Set the option bit   */
                if(*chpt == '+')
                    chpt++;
              }
              optchar = *chpt++;
              break;
            case 'o':
            /* Option 'o' - turn cache on.  */
              if(*chpt == '-') {
                opt |= OPT_OFF;
                chpt++;
              } else {
                opt &= ~OPT_OFF;
                if(*chpt == '+')
                    chpt++;
              }
              optchar = *chpt++;
              break;
            case 'b':
            /* Option 'b' - turn background writing
             * (== write caching) on.  */
              if(*chpt == '-') {
                opt &= ~OPT_WR_ON;
                chpt++;
              } else {
                opt |= OPT_WR_ON;
                if(*chpt == '+')
                    chpt++;
              }
              optchar = *chpt++;
              break;
            case 'i':
            /* Option 'i' - write immediately
             * (or enable delayed writing if 'i-') in effect only if
             * write caching (background writing) is on.  */
              if(*chpt == '-') {
                opt &= ~OPT_DW_OFF;
                chpt++;
              } else {
                opt |= OPT_DW_OFF;
                if(*chpt == '+')
                    chpt++;
              }
              optchar = *chpt++;
              break;
            case 'z':
            /* Option 'z' - freeze cache - no new sectors are read into
             * cache after freezing and only that are in cache may be written
             * in background.   */
              if(*chpt == '-') {
                opt &= ~OPT_FREEZE;
                chpt++;
              } else {
                opt |= OPT_FREEZE;
                if(*chpt == '+')
                    chpt++;
              }
              optchar = *chpt++;
              break;
            case 'f':
            /* Option 'z' - fix memory setting - disables automatic reallocation
             * of XMS memory when it is requested by other programs.  */
              if(*chpt == '-') {
                opt &= ~OPT_MEM;
                chpt++;
              } else {
                opt |= OPT_MEM;
                if(*chpt == '+')
                    chpt++;
              }
              optchar = *chpt;
              break;
            case 'r':
            /* reset all counters */
              if(reset_counters(drive, cmb_st.version))
                  printf(red_bold(Can\'t reset counters!) "\a\n");
              else
                  printf("Counters reset. ");
              optchar = *chpt++;
              break;
            default:
              printf(red_bold(Invalid option: ) bold('%c') "\n", optchar);
            case '?':
              usage();
          }
        }
      }
    }
    if(oldopt != opt) {
      if(change_opt(drive, cmb_st.version, opt))
        printf(red_bold(Can\'t change options!) "\a\n");
      else
        printf("Options changed.");
    } else
        printf("Options unchanged.");
    printf("\n");
  }

  r.x.ax=0x4404;                /* read again IOCtl packet */
  r.h.bl=drive;
  r.x.cx=sizeof(cmb_st);
  r.x.dx=(unsigned)&cmb_st;
  intdos(&r,&r);

  show_status(&cmb_st);   /* Show status returned by COMBI. */

}

show_status(struct combi_status *cmb_st)
{
  char  opt;

  printf("\n\t" bold(Current status:) "\n");

  printf("buffer size:  " cyan_bold(%5dK) "\n", cmb_st -> buff_size);

  printf("current size: " cyan_bold(%5dK) "\n", cmb_st -> curr_size);

  printf("total number of blocks:   " cyan_bold(%4d) " (" cyan_bold(%d) " sectors each)\n",
          cmb_st -> n_blocks, cmb_st -> bl_sect);

  printf("current number of blocks: " cyan_bold(%4d) " (" cyan_bold(%d) " - RAM disk, " cyan_bold(%d) " - cache)\n",
          cmb_st -> n_curr, cmb_st -> n_bl_RD, cmb_st -> n_bl_Cache);

  opt = cmb_st -> COMBI_options;
  if(opt & OPT_WR_ON) {				/* only if write caching is on */
    printf("dirty blocks: " cyan_bold(%d) ", errors: " cyan_bold(%d) "\n",
            cmb_st ->  n_dirty, cmb_st -> n_errors);
  };

  printf("\n\t" bold(Options in order:) "\n");

  if(!(opt & OPT_OFF)) {
    printf("cache is " cyan_bold(on) " (%s),\n",
           (opt & OPT_FREEZE) ? "frozen" : "not frozen");
  printf("write caching is " cyan_bold(%s) ",\n",
           (opt & OPT_WR_ON)  ? "on"     : "off");
	if(opt & OPT_WR_ON) {
    printf("delayed write is " cyan_bold(%s) ",\n",
             (opt & OPT_DW_OFF) ? "off"    : "on");
	};
  } else {
  printf("cache is " cyan_bold(off) ",\n");
  };
  printf("memory allocation is " cyan_bold(%s) ".\n",
         (opt & OPT_MEM)    ? "fixed"  : "not fixed");

  printf("\n\t" bold(Statistics:) "\n");

  printf("RAM disk reads: " cyan_bold(% 6u/%-6u) "\n",
          cmb_st -> read_RD_num, cmb_st -> read_RD_sect);

  printf("RAM disk writes:" cyan_bold(% 6u/%-6u) "\n",
          cmb_st -> write_RD_num, cmb_st -> write_RD_sect);

  if(!(opt & OPT_OFF)){
    printf("Hard disk reads - requested: " cyan_bold(% 6u/%-6u) ", passed to BIOS:" cyan_bold(% 6u/%-6u) "\n",
            cmb_st -> read_rq,    cmb_st -> read_sect,
            cmb_st -> read_rq_a,  cmb_st -> read_sect_a);
    printf("Hard disk writes - requested:" cyan_bold(% 6u/%-6u) ", passed to BIOS:" cyan_bold(% 6u/%-6u) "\n",
            cmb_st -> write_rq,   cmb_st -> write_sect,
            cmb_st -> write_rq_a, cmb_st -> write_sect_a);
  }
}

change_mem(int drive, int ver, int memch)
{
  unsigned char ctl[12];
  union REGS r;
  *(int *)&ctl = ver;
  if(memch > 0) {
    ctl[2] = CMD_EXPAND;    /* command code for COMBI-disk - expand memory */
    *(int *)&ctl[3] = memch;/* the amount of Kbytes to change memory size  */
  } else {
    ctl[2] = CMD_SHRINK;    /* command code for COMBI-disk - shrink memory */
    *(int *)&ctl[3] = - memch;
  }

  r.x.ax=0x4405;    /* DOS function: 'write IOCtl to block device' */
  r.h.bl=drive;     /* device number  */
  r.x.dx=(unsigned)&ctl;  /* address of IOCtl packet */
  r.x.cx=5;         /* IOCtl packet length  */
  intdos(&r,&r);
  if(r.x.cflag & 01)      /* test for error return code */
      return -1;
  else
      return 0;
}

change_opt(int drive, int ver, int opt)
{
  unsigned char ctl[12];
  union REGS r;
  *(int *)&ctl = ver;
  ctl[2] = CMD_CH_OPT;    /* command to COMBI-disk - change options */
  ctl[3] = opt;           /* the byte with new options follows the command */

  r.x.ax=0x4405;
  r.h.bl=drive;
  r.x.dx=(unsigned)&ctl;
  r.x.cx=4;
  intdos(&r,&r);
  if(r.x.cflag & 01)
      return -1;
  else
      return 0;
}

reset_counters(int drive, int ver)
{
  unsigned char ctl[12];
  union REGS r;
  *(int *)&ctl = ver;
  ctl[2] = CMD_RESET_C;   /* command to COMBI-disk - reset counters */
  ctl[3] = 7;             /* reset all three types of counters */

  r.x.ax=0x4405;
  r.h.bl=drive;
  r.x.dx=(unsigned)&ctl;
  r.x.cx=4;
  intdos(&r,&r);
  if(r.x.cflag & 01)
      return -1;
  else
      return 0;
}

usage()
{
  printf("\t" yellow_bold(COMBI-disk (C) control program.) "\n"
         "Copyright (C) 1992 by Vadim V. Vlasov, Moscow, Russia.\n");

  printf("Usage: " bold(COMBI [[+|-]#] [<option>[+|-]]...) "\n"
         "where:\n"
         "    " bold(# (number)) " - expand or shrink memory used by COMBI-disk,\n"
         "    " bold(n) " - don't return 'sector not found' error,\n"
         "    " bold(o) " - turn cache on ('" bold(o-) "' - turn off),\n"
         "    " bold(b) " - turn write caching on ('" bold(b-) "' - off),\n"
         "    " bold(i) " - start writing immediately ('" bold(i-) "' - delayed writing),\n"
         "    " bold(f) " - fix memory settings ('" bold(f-) "' - release),\n"
         "    " bold(z) " - freeze cache ('" bold(z-) "' - un-freese),\n"
         "    " bold(r) " - reset all counters.\n");
  exit(1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -