home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 17 / CD_ASCQ_17_101194.iso / dos / prg / sphinx / examples / tsr / clock.c__ < prev    next >
Encoding:
Text File  |  1994-07-06  |  6.3 KB  |  243 lines

  1. //
  2. //  NAME: CLOCK.C--
  3. //
  4. //  This program is an example of a **REMOVABLE** TSR
  5. //  that use a particular interrupt to communicate within the resident
  6. //  portion and the other
  7. //
  8. //  Written by Gerardo MAIORANO with the SPHINX C-- 0.190A in SALERNO (Italy)
  9. //  E-mail :    germai@ischia.dia.unisa.it || giufer@udsab.dia.unisa.it
  10. //
  11.  
  12. ?resize TRUE
  13. ?assumeDSSS TRUE
  14. ?parsecommandline TRUE
  15. ?include "WRITE.H--"
  16. ?include "DOS.H--"
  17. ?include "TSR.H--"
  18. ?include "GWRITE.H--"
  19. ?include "STRING.H--"
  20. ?define HI        0x5453    /* High TSR signature */
  21. ?define LO        0x5230    /* Low TSR signature  */
  22. ?define TSRINT    0x15      /* Interrupt used to communicate between TSR */
  23. ?define TIMERINT  0x1C      /* User Timer Tick    */
  24.  
  25. word oldtimerhandle[2]={};  /* Old Interrupt address handler for INT 1C */
  26. word oldtsrhandle[2]={};    /* Old Interrupt address handler for INT 15 */
  27. byte display="[00.00.00]";
  28. word cursor=0,pos=0;
  29.  
  30. //
  31. //  This function was called 18.2 time/sec and read the system time and
  32. //  display it on the upper right corner.
  33. //
  34. interrupt timerhandle()   
  35. {
  36. $ PUSHF                     //
  37. $ CS:                       //   Simulates the call to the old handler
  38. $ CALL FAR oldtimerhandle;  //
  39. $ PUSH DS                   //
  40. $ PUSH SI                   //  Preserve all the necessary
  41. $ PUSH AX                   //  Registers
  42. $ PUSH BX                   //
  43. $ PUSH CX                   //
  44. $ PUSH DX                   //
  45. DS = CS;
  46. AH=2;                       // get current status of led
  47. $ INT 0x16
  48. if(AL&16!=16){              // if scroll lock is not active show the clock
  49.   AH=2;                     // get current time from bios
  50.   $INT 0x1A
  51.   BL=CL;                    //
  52.   SI=#display;              //
  53.   CL=4;                     //  Transform the time which is
  54.   AL=CH;                    //  in BCD format into the ASCII format
  55.   $SAR AL,CL                //
  56.   IF(ZEROFLAG){             //
  57.     AL+=32;
  58.   }
  59.   ELSE{
  60.     AL+=48;
  61.   }
  62.   DSBYTE[SI+1]=AL;
  63.   AH=CH;
  64.   AH&=0x0F;
  65.   AH+=48;
  66.   DSBYTE[SI+2]=AH;
  67.   AL=BL;
  68.   $SAR AL,CL
  69.   AL+=48;
  70.   DSBYTE[SI+4]=AL;
  71.   AH=BL;
  72.   AH&=0x0F;
  73.   AH+=48;
  74.   DSBYTE[SI+5]=AH;
  75.   AL=DH;
  76.   $SAR AL,CL
  77.   AL+=48;
  78.   DSBYTE[SI+7]=AL;
  79.   AH=DH;
  80.   AH&=0x0F;
  81.   AH+=48;
  82.   DSBYTE[SI+8]=AH;
  83.  
  84.   AH=3;                 // get cursor position and size
  85.   BH=0;
  86.   $INT 0x10;
  87.   cursor=CX;
  88.   pos=DX;
  89.   CX=0x2000;
  90.   AH=1;
  91.   $INT 0x10             // and then hide it
  92.   AH=0x0F;
  93.   $INT 0x10             // tell me how many columns are on the screen
  94.   DH=0;
  95.   DL=AH-10;
  96.   AH=2;
  97.   $INT 0x10                 // display the cursor in the upper right corner
  98.   @GWRITESTR(#display,15);  // display the time
  99.   DX=pos;
  100.   AH=2;
  101.   $INT 0x10                 // reset the old saved cursor position
  102.   CX=cursor;
  103.   AH=1;
  104.   $INT 0x10                 // reset the old saved cursor size
  105. }
  106. $ POP DX                    //
  107. $ POP CX                    //
  108. $ POP BX                    // Restore the original Register's state
  109. $ POP AX                    //
  110. $ POP SI                    //
  111. $ POP DS                    //
  112. }
  113.  
  114. //
  115. // This function tell me if the resident portion is installed or NOT,
  116. // and in case of removing the resident portion, restore the old handler
  117. //
  118. interrupt comtsrhandle() 
  119. {
  120. IF(AX==0x5200){
  121.   IF(CX==HI){
  122.     IF(DX==LO){
  123.       BX=CS;
  124.       CX><DX;
  125.     }
  126.     ELSE{
  127.       $JMP NEXT
  128.     }
  129.   }
  130.   ELSE{
  131.     $JMP NEXT
  132.   }
  133. }
  134. ELSE IF(AX==0X5201){
  135.   IF(CX==HI){
  136.     IF(DX==LO){
  137.       $PUSH DS
  138.       DX=CSWORD[#oldtimerhandle];
  139.       DS=CSWORD[#oldtimerhandle+2];
  140.       @SETINTVECT( ,TIMERINT,DS,DX);
  141.       DX=CSWORD[#oldtsrhandle];
  142.       DS=CSWORD[#oldtsrhandle+2];
  143.       @SETINTVECT( ,TSRINT,DS,DX);
  144.       BX=CS;
  145.       $POP DS
  146.     }
  147.     ELSE{
  148.       $JMP NEXT
  149.     }
  150.   }
  151.   ELSE{
  152.     $JMP NEXT
  153.   }
  154. }
  155. ELSE {
  156.   NEXT:
  157.   $ CS:
  158.   $ JMP FAR oldtsrhandle;
  159. }
  160. }
  161.  
  162. //
  163. //
  164. //
  165. main ()
  166. {
  167. WRITESTR("RESIDENT CLOCK 1.0 - CopyLeft by Gerardo Maiorano.\n");
  168. if(@PARAMCOUNT()==0){   // process the command line and if there aren't
  169.   AX=0x5200;            // check if we have already installed CLOCK
  170.   CX=HI;                // sometime
  171.   DX=LO;
  172.   $INT 0X15
  173.   IF(CX==LO){
  174.     IF(DX==HI){
  175.       WRITESTR("Resident portion of CLOCK already installed\007.\n");
  176.       EXIT(0);
  177.     }
  178.   }
  179.   GETINTVECT(#oldtsrhandle,TSRINT);        // This is the heart of the
  180.   SETINTVECT( ,TSRINT,CS,#comtsrhandle);   // program, performing the
  181.   GETINTVECT(#oldtimerhandle,TIMERINT);    // necessary work to do make TSR
  182.   SETINTVECT( ,TIMERINT,CS,#timerhandle);
  183.   WRITESTR("Resident portions of CLOCK installed.\n");
  184.   ES=CSWORD[0x2C];
  185.   AH=0x49;
  186.   $INT 0x21                 // Free the environment block
  187.   @ KEEP( , , ,#main+1);
  188. }
  189. else{                       // If there are parameters of the command line
  190.   @STR_UP(PARAMSTR(0));     // parse it and see if is REMOVE
  191.   AL=@STRCMP(PARAMSTR(0),"REMOVE");
  192.   if(AL==0){
  193.     AX=0x5200;
  194.     CX=HI;
  195.     DX=LO;
  196.     $INT 0X15               // Check if the CLOCK is really installed
  197.     IF(CX==LO){             // If YES, check that if after CLOCK there are
  198.       IF(DX==HI){           // other TSR proggy
  199.     AX=BX;
  200.     $DEC AX
  201.     ES=AX;
  202.     DX=CS;
  203.     P1:                      // Scan for next entry in MCB chain
  204.     AX+=ESWORD[3];       // looking for themself
  205.     $INC AX              // Go to next MCB entry
  206.     ES=AX;
  207.     $CMP DX,ESWORD[1]
  208.     $JZ A1
  209.     IF(ESWORD[1]!=0){   // If there are other TSR installed after CLOCK
  210.       WRITESTR("Can't remove resident portion !\007\n");  // Exit whit error
  211.       EXIT(1);
  212.     }
  213.     $JMP P1             // Otherwise remove it
  214.     A1:
  215.     $PUSH AX            //
  216.     $INC AX             //
  217.     $CMP AX,DX          // If the CS of the stand-alone copy is egual
  218.     $POP AX             // to that the last MCB checked then we are
  219.     $JNZ P1             // sure that there aren't ANY other TSR proggy
  220.     AX=0x5201;          //
  221.     CX=HI;              //
  222.     DX=LO;              //
  223.     $INT 0x15           //
  224.     ES=BX;
  225.     AH=0x49;
  226.     $INT 0x21           // Free the resident portion of CLOCK
  227.     WRITESTR("CLOCK removed from memory !!!\n");
  228.     EXIT(0);
  229.       }
  230.     }
  231.     WRITESTR("CLOCK not installed.\007\n");
  232.     EXIT(0);
  233.   }
  234.   else{
  235.     WRITESTR("Usage:\nCLOCK : Install the resident portion \n");
  236.     WRITESTR("CLOCK ?       : Show this help\n");
  237.     WRITESTR("CLOCK REMOVE  : Try to remove CLOCK from memory.\n");
  238.     EXIT(0);
  239.   }
  240. }
  241. }
  242.  
  243. /* end of CLOCK.C-- */