📄 tsrexamp.c
字号:
old_int24 = _dos_getvect(0x24);
/* set our interrupts functions */
_dos_setvect(0x1b, new_int1b);
_dos_setvect(0x23, new_int23);
_dos_setvect(0x24, new_int24);
/* save current PSP and set to ours */
/* not needed for DOSSWAP, but can be used by application */
foreground_psp = GetPSP();
SetPSP(_psp); // _psp in STDLIB.H
#ifndef DOS_SWAP
/* get foreground DTA */
regs.h.ah = GET_DTA;
intdosx(®s, ®s, &sregs);
foreground_dta_seg = sregs.es;
foreground_dta_off = regs.x.bx;
#endif
/* set up our DTA */
regs.h.ah = SET_DTA;
regs.x.dx = 0x80; /* use default in PSP area */
sregs.ds = _psp;
intdosx(®s, ®s, &sregs);
#ifndef DOS_SWAP
/* Get Extended Error Information */
GetExtErr(&ErrInfo);
#endif
/* suck up key(s) in buffer */
while (_bios_keybrd(_KEYBRD_READY))
_bios_keybrd(_KEYBRD_READ);
/* your code goes here */
application();
#ifdef DOS_SWAP
RestoreDosSwap();
#else
/* put back extended error information */
SetExtErr(&ErrInfo);
/* put back original DTA */
regs.h.ah = SET_DTA;
regs.x.dx = foreground_dta_off;
sregs.ds = foreground_dta_seg;
intdosx(®s, ®s, &sregs);
/* put back original PSP */
SetPSP(foreground_psp);
#endif
/* put back original INTS */
_dos_setvect(0x1b, old_int1b);
_dos_setvect(0x23, old_int23);
_dos_setvect(0x24, old_int24);
}
restore_stack();
}
// only restores OldInt if someone hasn't grabbed away Vect
int UnlinkVect(int Vect, INTVECT NewInt, INTVECT OldInt)
{
if (NewInt == _dos_getvect(Vect))
{
_dos_setvect(Vect, OldInt);
return 0;
}
return 1;
}
void tsr_exit(void)
{
set_stack();
/* put interrupts back the way they were, if possible */
if (!(UnlinkVect(8, new_int8, old_int8) |
UnlinkVect(9, new_int9, old_int9) | // Do not use ||, we
UnlinkVect(0x28, new_int28, old_int28) | // don't want early out
UnlinkVect(0x13, new_int13, old_int13) |
#ifdef DOS_SWAP
UnlinkVect(0x2a, new_int2a, old_int2a) |
#endif
UnlinkVect(0x2f, new_int2f, old_int2f) ))
{
// Set parent PSP, stored in our own PSP, to the current PSP
*(int far *)(((long)_psp << 16) + PSP_PARENT_PSP) = GetPSP();
// Set terminate address in our PSP
*(long far *)(((long)_psp << 16) + PSP_TERMINATE) = TerminateAddr;
/* set psp to be ours */
SetPSP(_psp);
/* exit program */
bdos(DOS_EXIT, 0, 0);
}
restore_stack();
}
void usage(char *progname)
{
fputs("Usage: ", stdout);
puts(progname);
puts(" [-d to deinstall] [-k keycode shift-status] [-f multiplex id]");
puts(" Valid multiplex id");
puts(" 00 through 15 specifies a unique INT 2F ID");
puts(" Valid shift-status is any combination of:");
puts(" 1 = Right Shift");
puts(" 2 = Left Shift");
puts(" 4 = CTRL");
puts(" 8 = ALT");
exit(1);
}
void do_deinstall(char *progname)
{
fputs(progname, stdout);
switch (deinstall())
{
case 1:
puts(" was not installed");
break;
case 2:
puts(" deinstalled");
break;
default:
puts(" deactivated but not removed");
break;
}
exit(0);
}
int set_shift_key(unsigned sh)
{
/* figure out, report on shift statuses */
/* make sure shift key < 0x10 and non-zero */
if (((shift_key = sh) < 0x10) && shift_key)
{
printf("Activation: %s%s%s%sSCAN=%d\n",
shift_key & RIGHT_SHIFT ? "RIGHT " : "",
shift_key & LEFT_SHIFT ? "LEFT " : "",
shift_key & CTRL_KEY ? "CTRL " : "",
shift_key & ALT_KEY ? "ALT " : "",
hot_key);
return 1;
}
else /* error, bad param */
{
puts("Invalid Shift-Status");
return 0;
}
}
void parse_cmd_line(int argc, char *argv[])
{
int i;
int tmp;
for (i = 1; i < argc; i++) /* for each cmdline arg */
if ((argv[i][0] == '-') || (argv[i][0] == '/'))
switch(toupper(argv[i][1]))
{
case 'D':
do_deinstall(argv[0]);
break;
case 'K': /* set pop-up key sequence */
user_key_set = 1;
i++; /* bump to next argument */
if ((hot_key = atoi(argv[i])) != 0)
{
i++; /* bump to next argument */
if (! set_shift_key(atoi(argv[i])))
usage(argv[0]);
}
else
usage(argv[0]);
break;
case 'F': /* set multiplex ID */
i++; /* bump to next argument */
if ((tmp = atoi(argv[i])) < 0x10)
multiplex_id += tmp; /* range of C0-CF */
else
usage(argv[0]);
break;
default: /* invalid argument */
usage(argv[0]);
} /* end switch */
else
usage(argv[0]);
}
void main(int argc,char *argv[])
{
union REGS regs;
struct SREGS sregs;
unsigned far *fp;
unsigned memtop;
unsigned dummy;
InitInDos();
parse_cmd_line(argc,argv);
/* check if TSR already installed! */
regs.h.ah = multiplex_id;
regs.h.al = INSTALL_CHECK;
int86(0x2f, ®s, ®s);
if (regs.h.al == INSTALLED)
{
puts("TSR already installed");
fputs(argv[0], stdout); puts(" -D de-installs");
exit(1);
}
if (! user_key_set)
{
puts("Press ALT-D to activate TSR ");
printf("Multiplex ID = %0x \n",multiplex_id);
hot_key = HOT_KEY;
shift_key = ALT_KEY;
}
#ifdef DOS_SWAP
if (InitDosSwap() != 0)
{
puts("Error initializing DOS Swappable Data Area");
exit(1);
}
#endif
/* MALLOC a stack for our TSR section */
stack_ptr = malloc(STACK_SIZE);
stack_ptr += STACK_SIZE;
/* get interrupt vector */
old_int8 = _dos_getvect(8); /* timer interrupt */
old_int9 = _dos_getvect(9); /* keyboard interrupt */
old_int13 = _dos_getvect(0x13); /* disk intr, in TSRUTIL.ASM */
old_int28 = _dos_getvect(0x28); /* dos idle */
old_int2f = _dos_getvect(0x2f); /* multiplex int */
#ifdef DOS_SWAP
old_int2a = _dos_getvect(0x2a); /* dos internal int */
#endif
init_intr(); /* initilize int routines in TSRUTIL.ASM */
/* set interrupts to our routines */
_dos_setvect(8, new_int8);
_dos_setvect(9, new_int9);
_dos_setvect(0x13, new_int13); /* in TSRUTIL.ASM */
_dos_setvect(0x28, new_int28);
_dos_setvect(0x2f, new_int2f);
#ifdef DOS_SWAP
_dos_setvect(0x2a, new_int2a);
#endif
/* release environment back to MS-DOS */
FP_SEG(fp) = _psp;
FP_OFF(fp) = PSP_ENV_ADDR;
_dos_freemem(*fp);
/* release unused heap to MS-DOS */
/* All MALLOCS for TSR section must be done in TSR_INIT() */
/* calculate top of memory, shrink block, and go TSR */
segread(&sregs);
memtop = sregs.ds + PARAGRAPHS(stack_ptr) - _psp;
_dos_setblock(memtop, _psp, &dummy);
_dos_keep(0, memtop);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -