📄 combi.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 + -