home *** CD-ROM | disk | FTP | other *** search
- /* TSR.C:
- Terminate and Stay Ready (TSR) program written entirely in Turbo C.
- Bruce Eckel, Eisys Consulting, 1009 N. 36th St., Seattle, WA 98103.
- 7/87. The interrupt line on the parallel printer card (-ACK: pin
- 10 on the DB-25 connector) is allowed through to IRQ7, and the
- 8259A is configured to service the interrupt when -ACK is pulled to
- ground using a simple switch, TTL or CMOS logic. You can test it
- just by poking a wire from pin 10 to one of the ground pins
- (18-25). Each time you bring the line low, you will hear a brief
- beep. More information can be found on pp 274-276 of the Turbo C
- user's guide, and under "keep" in the reference guide.
- */
-
- #include <dos.h>
- #define INT_NUMBER 15 /* interrupt number to install this function
- into. Note IRQ7 on the PC card bus
- corresponds to interrupt handler 15 in the
- interrupt vector table. */
- #define PROG_SIZE 0x620 /* Run the Turbo C compiler with the
- options:linker:mapfile set to "segments."
- Look at the mapfile generated for this
- program. The "stop" address for the
- stack is the highest adress used -- set
- PROG_SIZE to this value for use with the
- "keep()" command */
-
- #define PPORT_BASE 0x378 /* Parallel port board base address for LPT1.
- This address is usually determined by
- either dip switches or jumpers. Change
- this if you're using LPT2 or some other
- address. */
-
- #define PIC_OCW1 0x21 /* Address of 8259A Programmable Interrupt
- Controller Operation Control Word 1. */
-
- void interrupt int_handler()
-
- /* "interrupt" is a special Turbo C compiler directive which causes
- all the registers to be pushed on entry and restored on exit. In
- addition, the special "return from interrupt" instruction is used to
- exit the routine (and interrupts are re-enabled), instead of a normal
- "return from subroutine" instruction, which a regular function call
- uses. The "interrupt" directive means you can write interrupt
- routines without using assembly language (hooray for increased
- productivity!). */
-
- {
- extern void beep(int time); /* function prototype shows the compiler
- how a proper function call should
- look. */
- int i;
- beep(30); /* All we do is make a little noise, but you can add all
- kinds of stuff here (as long as you don't make any DOS
- or BIOS calls, since you might be interrupting one and
- they aren't re-entrant. */
-
- /* tell the 8259A Interrupt Controller we're done executing IRQ7 */
- outportb(0x20,0x67); /* specific EOI for IRQ7 */
-
- }
-
- main() /* this installs the interrupt, sets up the hardware, and
- exits leaving the program resident. Main is never used
- again. */
- {
- setvect(INT_NUMBER,int_handler); /* passes the ADDRESS of the
- beginning of the
- int_handler() function. */
-
- /* change the bit on the parallel board to allow the -ACK
- interrupt to pass through to IRQ7 on the PC card bus. */
- outportb(PPORT_BASE + 2, 0x10);
-
- /* zero top bit of OCW1 to allow IRQ7 to be serviced. Note we get
- the current OCW1, force the top bit to 0 and put it back out --
- this retains the rest of the word (which affects other aspects
- of the machine) to prevent undesirable side effects).
- I know all this writing-to-hardware stuff must seem mysterious,
- but if you really want to understand it you have to read the
- 8259A manual (not pretty) and stare at the diagrams for the
- printer board (see text). */
- outportb(PIC_OCW1, inportb(PIC_OCW1) & 0x7f);
-
- keep(0,PROG_SIZE); /* first parameter is exit status */
- }
-
- void
- beep(int time)
- /* beeps the speaker, carefully restoring the state of the control
- port. ("Remember, scouts: leave things BETTER than you found
- them...").
- Taken directly from the Turbo C User's Guide, page 275. */
- {
- char originalbits, bits;
- int i,j;
-
- /* get the current control port setting */
- bits = originalbits = inportb(0x61);
-
- for (i = 0; i <= time; i++) {
- /* turn off the speaker for a while */
- outportb(0x61, bits & 0xfc);
- for (j=0; j <= 100; j++)
- ;
- /* now turn it on for awhile */
- outportb(0x61, bits | 2);
- for (j = 0; j <= 100; j++)
- ;
- }
-
- /* restore the control port setting */
- outportb(0x61, originalbits);
- }