home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / nvdc87 / parallel / tsr.c < prev   
Text File  |  1987-09-01  |  5KB  |  114 lines

  1. /* TSR.C:
  2.    Terminate and Stay Ready (TSR) program written entirely in Turbo C.
  3.    Bruce Eckel, Eisys Consulting, 1009 N. 36th St., Seattle, WA 98103.
  4.    7/87.  The interrupt line on the parallel printer card (-ACK: pin
  5.    10 on the DB-25 connector) is allowed through to IRQ7, and the
  6.    8259A is configured to service the interrupt when -ACK is pulled to
  7.    ground using a simple switch, TTL or CMOS logic.  You can test it
  8.    just by poking a wire from pin 10 to one of the ground pins
  9.    (18-25).  Each time you bring the line low, you will hear a brief
  10.    beep.  More information can be found on pp 274-276 of the Turbo C
  11.    user's guide, and under "keep" in the reference guide.
  12. */
  13.  
  14. #include <dos.h>
  15. #define INT_NUMBER 15     /* interrupt number to install this function
  16.                           into.  Note IRQ7 on the PC card bus
  17.                           corresponds to interrupt handler 15 in the
  18.                           interrupt vector table.  */
  19. #define PROG_SIZE 0x620  /* Run the Turbo C compiler with the
  20.                             options:linker:mapfile set to "segments."
  21.                             Look at the mapfile generated for this
  22.                             program.  The "stop" address for the
  23.                             stack is the highest adress used -- set
  24.                             PROG_SIZE to this value for use with the
  25.                             "keep()" command */
  26.  
  27. #define PPORT_BASE 0x378 /* Parallel port board base address for LPT1.
  28.                             This address is usually determined by
  29.                             either dip switches or jumpers.  Change
  30.                             this if you're using LPT2 or some other
  31.                             address. */
  32.  
  33. #define PIC_OCW1 0x21    /* Address of 8259A Programmable Interrupt
  34.                             Controller Operation Control Word 1.  */
  35.  
  36. void interrupt int_handler()
  37.  
  38. /* "interrupt" is a special Turbo C compiler directive which causes
  39. all the registers to be pushed on entry and restored on exit.  In
  40. addition, the special "return from interrupt" instruction is used to
  41. exit the routine (and interrupts are re-enabled), instead of a normal
  42. "return from subroutine" instruction, which a regular function call
  43. uses.  The "interrupt" directive means you can write interrupt
  44. routines without using assembly language (hooray for increased
  45. productivity!).  */
  46.  
  47. {
  48. extern void beep(int time); /* function prototype shows the compiler
  49.                                how a proper function call should
  50.                                look. */
  51. int i;
  52. beep(30);   /*  All we do is make a little noise, but you can add all
  53.                 kinds of stuff here (as long as you don't make any DOS
  54.                 or BIOS calls, since you might be interrupting one and
  55.                 they aren't re-entrant.  */
  56.  
  57. /* tell the 8259A Interrupt Controller we're done executing IRQ7 */
  58. outportb(0x20,0x67);   /* specific EOI for IRQ7 */
  59.  
  60. }
  61.  
  62. main()  /* this installs the interrupt, sets up the hardware, and
  63.            exits leaving the program resident.  Main is never used
  64.            again.  */
  65. {
  66.     setvect(INT_NUMBER,int_handler);  /* passes the ADDRESS of the
  67.                                          beginning of the
  68.                                          int_handler() function. */
  69.  
  70.    /* change the bit on the parallel board to allow the -ACK
  71.       interrupt to pass through to IRQ7 on the PC card bus. */
  72.       outportb(PPORT_BASE + 2, 0x10);
  73.  
  74.    /* zero top bit of OCW1 to allow IRQ7 to be serviced.  Note we get
  75.       the current OCW1, force the top bit to 0 and put it back out --
  76.       this retains the rest of the word (which affects other aspects
  77.       of the machine) to prevent undesirable side effects).
  78.       I know all this writing-to-hardware stuff must seem mysterious,
  79.       but if you really want to understand it you have to read the
  80.       8259A manual (not pretty) and stare at the diagrams for the
  81.       printer board (see text). */
  82.       outportb(PIC_OCW1, inportb(PIC_OCW1) & 0x7f);
  83.  
  84.       keep(0,PROG_SIZE);  /* first parameter is exit status */
  85. }
  86.  
  87. void
  88. beep(int time)
  89. /* beeps the speaker, carefully restoring the state of the control
  90.    port.  ("Remember, scouts: leave things BETTER than you found
  91.    them...").
  92.    Taken directly from the Turbo C User's Guide, page 275.  */
  93. {
  94. char originalbits, bits;
  95. int i,j;
  96.  
  97.    /* get the current control port setting */
  98.    bits = originalbits = inportb(0x61);
  99.  
  100.    for (i = 0; i <= time; i++) {
  101.    /* turn off the speaker for a while */
  102.     outportb(0x61, bits & 0xfc);
  103.     for (j=0; j <= 100; j++)
  104.         ;
  105.    /* now turn it on for awhile */
  106.     outportb(0x61, bits | 2);
  107.     for (j = 0; j <= 100; j++)
  108.         ;
  109.    }
  110.  
  111.    /* restore the control port setting */
  112.    outportb(0x61, originalbits);
  113. }
  114.