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

📄 tsrexamp.c

📁 汇编源代码大全
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 
TSREXAMP.C
by Raymond J. Michels
with revisions by Tim Paterson
and Andrew Schulman
*/

#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <bios.h>
#include "tsr.h"

#define STACK_SIZE      8192  /* must be 16 byte boundaray */
#define SET_DTA         0x1a  /* SET Disk Transfer Address */
#define GET_DTA         0x2f  /* GET Disk Transfer Address */   

#define DOS_EXIT        0x4C  /* DOS terminate (exit) */

#define KEYBOARD_PORT   0x60  /* KEYBOARD Data Port */

#define PSP_TERMINATE   0x0A  /* Termination addr. in our PSP */
#define PSP_PARENT_PSP  0x16  /* Parent's PSP from our PSP */
#define PSP_ENV_ADDR    0x2c  /* environment address from PSP */

#define HOT_KEY         32    /* Hot Key along with ALT (D)*/

#define RIGHT_SHIFT     1
#define LEFT_SHIFT      2
#define CTRL_KEY        4
#define ALT_KEY         8

#define MULTIPLEX_ID    0xC0
#define INSTALL_CHECK   0x00
#define INSTALLED       0xFF
#define DEINSTALL       0x01

#define PARAGRAPHS(x)   ((FP_OFF(x) + 15) >> 4)

unsigned char multiplex_id = MULTIPLEX_ID;    
char far *stack_ptr;           /* pointer to TSR stack */
unsigned ss_save;              /* slot for stack segment register */
unsigned sp_save;              /* slot for stack pointer register */
int tsr_already_active = 0;    /* true if TSR active */
int popup_while_dos_busy = 0;  /* true if hot key hit while dos busy */
int int_28_in_progress = 0;    /* true if INT 28 in progress */
int unsafe_flag = 0;           /* true if INT 13 in progress */
unsigned keycode;                
unsigned foreground_psp;       /* PSP of process we've interrupted */
unsigned foreground_dta_seg;   /* DTA of process we've interrupted */
unsigned foreground_dta_off;
char buf[20];                  /* work buffer */
unsigned long TerminateAddr;   /* used during de-install */
union REGS regs;               /* register work structures */
struct SREGS sregs;     
struct ExtErr ErrInfo;         /* save area for extended error info */
int hot_key;                   /* keycode for activation */
int shift_key;                 /* shift status bits (alt,  ctrl..) */
int user_key_set = 0;
    
/* Save areas for old interrupt pointers */
INTVECT old_int8, old_int9, old_int10, old_int13, old_int1b, old_int23;
INTVECT old_int24, old_int28, old_int2f;

#ifdef DOS_SWAP
extern int dos_critical;     /* used by DOSSWAP.C */
INTVECT old_int2a;
void interrupt far new_int2a(INTERRUPT_REGS);
#endif

/* PROTOTYPES FOR THIS MODULE */
void interrupt far new_int8(INTERRUPT_REGS);
void interrupt far new_int9(INTERRUPT_REGS);
extern void interrupt far new_int13(void);  /* in TSRUTIL.ASM */
void interrupt far new_int1b(INTERRUPT_REGS);
void interrupt far new_int23(INTERRUPT_REGS);
void interrupt far new_int24(INTERRUPT_REGS);
void interrupt far new_int28(INTERRUPT_REGS);
void interrupt far new_int2f(INTERRUPT_REGS);
void tsr_function(void);
void tsr_exit(void);
void usage(char *);
int UnlinkVect(int Vect, INTVECT NewInt, INTVECT OldInt);
void parse_cmd_line(int argc, char *argv[]);
void main(int argc,char *argv[]);

/*********
* TIMER INTERRUPT HANDLER
*********/
void interrupt far new_int8(INTERRUPT_REGS r)
{
#ifdef DOS_SWAP
    if (!tsr_already_active && popup_while_dos_busy &&
        !dos_critical && !unsafe_flag)
#else
    if (!tsr_already_active && popup_while_dos_busy &&
        !DosBusy() && !unsafe_flag) 
#endif
    {
        popup_while_dos_busy = 0;
        tsr_already_active = 1;
		(*old_int8)();	/* process timer tick */
        _enable(); /* turn interrupts back on */
        tsr_function();
        tsr_already_active = 0;
    }
	else
		(*old_int8)();	/* process timer tick */
} 

/**********
* KEYBOARD INTERRUPT HANDLER
**********/
void interrupt far new_int9(INTERRUPT_REGS r)
{
    if (! tsr_already_active)
    {
         if ((keycode = inp(KEYBOARD_PORT)) != hot_key)
            _chain_intr(old_int9);

         if ((_bios_keybrd(_KEYBRD_SHIFTSTATUS) & 
            shift_key) == shift_key)
         {      
#ifdef USES_DISK
            if (!unsafe_flag)
            {
#endif
                popup_while_dos_busy = 0;   
                tsr_already_active = 1;
                (*old_int9)();     /* send key to old int routine */
                tsr_function();
                tsr_already_active = 0; 

#ifdef USES_DISK
            }
            else
			{
                popup_while_dos_busy = 1;
				_chain_intr(old_int9);
			}
#endif
         }
         else
            _chain_intr(old_int9);
     }      
     else 
         _chain_intr(old_int9);     
} 

/*********
* CTRL-BREAK INTERRUPT HANDLER
*********/
void interrupt far new_int1b(INTERRUPT_REGS r)
{
    /* do nothing */
} 

/**********
* CTRL-C INTERRUPT HANDLER
**********/
void interrupt far new_int23(INTERRUPT_REGS r)
{
    /* do nothing */
} 

/**********
* CRTITICAL ERROR INTERRUPT HANDLER
**********/
void interrupt far new_int24(INTERRUPT_REGS r)
{
    if (_osmajor >= 3)
        r.ax = 3;   /* fail dos function */
    else
        r.ax = 0;        
} 

/**********
* DOS IDLE INTERRUPT HANDLER
**********/
void interrupt far new_int28(INTERRUPT_REGS r)
{
    int_28_in_progress++;

#ifdef DOS_SWAP
    if (popup_while_dos_busy && !dos_critical 
        && !tsr_already_active && !unsafe_flag)
#else
    if (popup_while_dos_busy && (!Int28DosBusy()) 
        && !tsr_already_active && !unsafe_flag) 
#endif
    {
         tsr_already_active = 1;
         tsr_function();
         tsr_already_active = 0;
    }

    int_28_in_progress--;
    _chain_intr(old_int28);  
} 

#ifdef DOS_SWAP
/*********
* DOS INTERNAL INTERRUPT HANDLER
*********/
void interrupt far new_int2a(INTERRUPT_REGS r)
{
   switch (r.ax & 0xff00)
   {
      case 0x8000:    /* start critical section */
         dos_critical++;
         break;
      case 0x8100:    /* end critical section */
      case 0x8200:    /* end critical section */
         if (dos_critical)    /* don't go negative */
            dos_critical--;
         break;
      default:
         break;
    }
   _chain_intr(old_int2a);
} 
#endif

/*********
* DOS MULTIPLEX INTERRUPT HANDLER
*********/
void interrupt far new_int2f(INTERRUPT_REGS r)
{
    unsigned ah = r.ax >> 8;
    unsigned al = r.ax & 0xFF;
    
    if (ah == multiplex_id)
    {
        if (al == INSTALL_CHECK)
            r.ax |= INSTALLED;
        else if (al == DEINSTALL)
        {
            // because of stack swap, pass arg in static variable.
             TerminateAddr = ((long)r.bx << 16) + r.dx;
             if (! tsr_already_active)  /* don't exit if we're active */
             {
                 _enable(); /* STI */
                 tsr_exit();
                 // If we got here, we weren't able to unlink
                 r.ax = 0xFFFF;  //let caller know we're still there
                 // MSC 6.0 /Ox optimizes the above instruction away
                 // get it back by using the value in ax
                 tsr_already_active = -r.ax;  
                 // set to 1 to prevent any more action
             }
         }
    }
    else
         _chain_intr(old_int2f);
} 

/**********
* TSR ACTIVE SECTION
**********/
void tsr_function()
{
    set_stack();

#ifdef DOS_SWAP
    if (SaveDosSwap() && !int_28_in_progress)
#else
    if (DosBusy() && !int_28_in_progress)
#endif
        popup_while_dos_busy = 1; /* set flag: next INT 8,28 activates us */
    else
    {
        popup_while_dos_busy = 0;

        /* save old interrupt-CTRL-BREAK, CTRL-C and CRIT ERROR */ 
        old_int1b = _dos_getvect(0x1b); 
        old_int23 = _dos_getvect(0x23); 

⌨️ 快捷键说明

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