home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Program...: ontickC.c
- ** Author....: Brenton Farmer
- ** Date......: 10/10/91
- ** Purpose...: C code to support Clipper ontick() function.
- **
- ** Revision..: 1.1 02/15/92 Changed code to support indos flag checking
- ** 1.2 03/29/92 Changed operation to use hotkey to invoke udf
- ** 1.3 03/30/92 Added non int 21 keyboard stuff routine
- */
-
- #include "extend.h"
-
- typedef struct {
- unsigned es, ds, di, si, bp, sp, bx, dx, cx, ax, ip, cs, flags;
- } INTERRUPT_REGS;
-
- void ( interrupt far *old_int8)();
- void interrupt far C10ckISR( INTERRUPT_REGS);
- int StuffScanCode( int);
-
- extern void ( interrupt far *_getvector( unsigned int))();
- extern void _setvector( unsigned int, void( interrupt far *)());
- extern char * _getindosAddress();
-
-
- /*
- ** Declare Global Variables
- */
- int gTicks = 0; // Call Clipper routine every Ticks
- int gTickerCount = 0; // How many ticks have elapsed
- int gHotKey = 0; // ScanCode to put on keyboard buffer
-
- char far *indos = 0; // Address of DOS safe flag
-
-
- /*
- ** Logical C10ckSet( int TickTime, int ScanCode)
- **
- ** Note: C10ckSet( 0, 0); to turns off ticker
- */
- CLIPPER C10ckSet()
- {
- static int TickerIsActive = 0; // 1 if Ticker active, 0 if not
- int ReturnValue = 0; // 0 if invalid parameters passed
- int TickValue = 0; // Hotkey stuff interval
-
- if ( PCOUNT == 2 && ISNUM(1) && ISNUM(2))
- {
- ReturnValue = 1;
- if ( ( TickValue = _parni( 1)) != 0) // If TickValue != 0 Setup Timer
- {
- gTicks = TickValue; // Stuff Hotkey from isr every (Ticks)
- gTickerCount = 0; // Time elapsed in ticks
- gHotKey = _parni(2); // Hotkey Scancode
-
- if ( indos == 0)
- indos = _getindosAddress(); // Get indos address
-
- if (!TickerIsActive) { // Don't allow double install
- old_int8 = _getvector( 0x08); // Get current int 8 isr
- _setvector( 0x08, C10ckISR); // Set int 8 to my isr
- }
- TickerIsActive = 1; // Ticker is now installed
- }
- else {
- if ( TickerIsActive)
- _setvector( 0x08, old_int8); // Restore the original isr
-
- TickerIsActive = 0;
- gHotKey = 0;
- gTicks = 0;
- gTickerCount = 0;
- }
- }
-
- _retl( ReturnValue);
- }
-
-
- /*
- **
- **
- */
- void interrupt far C10ckISR( INTERRUPT_REGS r)
- {
- static int Busy = 0;
-
- (*old_int8)(); // Execute old handler
-
- if ( !Busy) { // Busy must be 0 (Prevents recursion)
- ++Busy; // Increment Busy flag
- if ( ++gTickerCount >= gTicks) // Has the appropriate time passed
- if (! *indos)
- if ( StuffScanCode( gHotKey)) // Stuff keyboard with hot-key
- gTickerCount = 0; // Reset ticker Timer
- --Busy; // Decrement Busy Flag
- }
- }
-
-
- /*
- ** Stuff Scancode into keyboard buffer.
- **
- ** NOTE: Since this routine is called from within my int8 handler
- ** it is entered with interrupts disabled. In order to keep
- ** this routine to a minimum -- NO checking is done to ensure
- ** a valid scancode. I based this code on an assembly language
- ** fragment from Ted Mean's putkey.asm routine in the
- ** nanforum lib.
- */
- int StuffScanCode( int ScanCode)
- {
- static int *Tail = (int *) 0x0000041C;
-
- int NewKeyBuff;
-
- if (! ScanCode) // Don't allow 0 scancode
- return ( FALSE);
-
- NewKeyBuff = *Tail + 2;
- if ( NewKeyBuff == 0x003E) // If NewKeyBuff== Buff maxbyte
- NewKeyBuff = 0x001E; // Set NewKeyBuff= Buff minbyte
-
- if ( NewKeyBuff == *((int *) 0x0000041A)) // If NewKeyBuff== Buffer Head
- return ( FALSE); // then keyboard Buffer is full
-
- *((int *) ((unsigned long)( *Tail + 0x0400))) = ScanCode;
- *Tail = NewKeyBuff;
-
- return ( TRUE);
- }
-