home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
nvdc87
/
parallel
/
tsr.c
< prev
Wrap
Text File
|
1987-09-01
|
5KB
|
114 lines
/* 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);
}