home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 8
/
CDASC08.ISO
/
NEWS
/
677
/
TSRTOOLS
/
HOTKEY.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-07
|
11KB
|
523 lines
/*
hotkey.C
Version 1.5
Hotkey Viewer and Changer
Copyright (C) 1993, Geoff Friesen B.Sc.
All rights reserved.
Developed with: Borland C++ 3.1
*/
/*
set ti=c:\borlandc\include
t hotkey -hh -x
The BIOS memory location 0040:0084 is set to the number of
screen rows less one. For example, if the screen has been
set to 25 lines then the value 24 would be stored here. A
value of 49 would be stored if 50-line mode were in effect
(on VGA adaptors). This address is used by recent adaptor
BIOSes. Older BIOSes do not use it. Therefore, assume it
to be valid if it returns a 24, 42, or 49. The 42 is used
in EGA 43-line mode.
This program assumes that the addresses for the signature,
hotkey letter, and hotkey scancode have not been changed.
These addresses are critical and should never be changed.
HOTKEY LETTER ADDRESS -> 0x0103 (single byte)
HOTKEY SCANCODE ADDRESS -> 0x0104 (single byte)
SIGNATURE ADDRESS START -> 0x010D (multiple bytes)
The signature always begins with the characters "TSR:" and
is followed by one to eight ASCII characters which is fol-
lowed by an ASCII NULL byte terminator (ASCII 0).
This TSR uses a GOTO statement in the main () function. I
tend to use GOTOs in the area of exception handling.
*/
#pragma inline
#if !defined(__TINY__)
#error Tiny Memory Model Expected
#endif
#include "tsrlib.H"
char *title = "\r\n"
"╔═════════════════════════════════════════════════╗\r\n"
"║ ▒ ▒ ▒▒▒ ▒▒▒▒▒ ▒ ▒ ▒▒▒▒▒ ▒ ▒ ║\r\n"
"║ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ║\r\n"
"║ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ║\r\n"
"║ ▒▒▒▒▒ ▒ ▒ ▒ ▒▒ ▒▒▒▒ ▒▒▒ Version 1.5 ║\r\n"
"║ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ║\r\n"
"║ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ║\r\n"
"║ ▒ ▒ ▒▒▒ ▒ ▒ ▒ ▒▒▒▒▒ ▒ ║\r\n"
"║ ║\r\n"
"║ Copyright (C) 1993, Geoff Friesen B.Sc. ║\r\n"
"║ All rights reserved. ║\r\n"
"╚═════════════════════════════════════════════════╝\r\n"
"$";
int bw [] =
{
WHITE, /* border */
LIGHTGRAY << 4, /* lightbar */
LIGHTGRAY /* normal text */
};
int color [] =
{
GREEN, /* border */
LIGHTGRAY << 4, /* lightbar */
(BLUE << 4) | WHITE /* normal text */
};
#define NATTR (sizeof(bw)/sizeof(bw [0]))
int attr [NATTR];
#define FREEMCB 0
#define BLOCMCB 'M'
#define LASTMCB 'Z'
#define KEYOFS 0x103
#define SIGOFS 0x10d
#define MAXPSP 100
#define NCOLS 18
#define NROWS 16
char buffer [(NCOLS+3)*(NROWS+3)*2];
int column = 1;
int row;
int srow = -1; /* suggested row */
int currow;
int ctsr;
int ntsr;
int psps [MAXPSP];
void change_key (int key);
void down (int nlines);
void end (void);
void home (void);
char *info (int row);
void refresh (void);
int scan (void);
void up (int nlines);
void main (void)
{
int cshape, i, key, nrows, vmode, x, y;
if ((vmode = v_getmode ()) != BW80 && vmode != C80 && vmode != MONO)
return;
nrows = peekb(0x40, 0x84)+1;
if (nrows != 25 && nrows != 43 && nrows != 50)
nrows = 25;
row = (srow == -1 || srow+NROWS+2 > nrows) ? 1 : srow;
for (i = 0; i < NATTR; i++)
attr [i] = (vmode == C80) ? color [i] : bw [i];
cshape = v_getshape ();
v_setshape (0x2000); /* hide cursor */
x = v_wherex ();
y = v_wherey ();
v_screen (SCREEN_SAVE, column, row, NCOLS+3, NROWS+3, buffer);
v_setattr (attr [0]);
v_border (BLOCK_LINE, column, row, NCOLS+2, NROWS+2);
v_shadow (column, row, NCOLS+2, NROWS+2);
v_setattr (attr [2]);
v_clear (column+1, row+1, NCOLS, NROWS);
if (scan () == -1)
{
v_gotoxy (column+1, row+1);
v_cputs ("Scan unsuccessful.");
v_gotoxy (column+1, row+3);
v_cputs (" Press any key.");
(void) k_fetch ();
goto main_exit;
}
ctsr = 0;
currow = 1;
refresh ();
do
{
if ((key = k_fetch ()) == ESC)
break;
if (isalpha (key) || isdigit (key))
{
change_key (key);
continue;
}
if (ntsr > 1)
switch (key)
{
case DOWN : down (1);
break;
case END : end ();
break;
case HOME : home ();
break;
case PGDN : down (16);
break;
case PGUP : up (16);
break;
case UP : up (1);
}
}
while (1);
main_exit:
v_screen (SCREEN_RESTORE, column, row, NCOLS+3, NROWS+3, buffer);
v_gotoxy (x, y);
v_setshape (cshape);
}
void change_key (int key)
{
static char scancodes [] =
{
30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50, /* A-M */
49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, /* N-Z */
11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0 /* 0-9 */
};
if (key >= 'Z') /* convert to uppercase */
key -= 32;
pokeb(psps [ctsr], KEYOFS, key);
pokeb(psps [ctsr], KEYOFS+1, isalpha (key) ? scancodes [key-'A'] :
scancodes [key-'0'+26]);
v_gotoxy (column+5, row+currow);
v_setattr (attr [1]);
v_putch (key, 1);
}
void down (int nlines)
{
int i, dnlines;
if (ctsr == ntsr-1)
return;
v_setattr (attr [2]);
v_gotoxy (column+1, row+currow);
v_cputs (info (ctsr));
dnlines = min(ntsr-1-ctsr, nlines);
for (i = 1; i <= dnlines; i++)
{
if (currow != NROWS)
currow++;
else
v_scroll (column+1, row+1, NCOLS, NROWS, SCROLL_UP,
1, attr [2]);
if (i == dnlines)
v_setattr (attr [1]);
v_gotoxy (column+1, row+currow);
v_cputs (info (++ctsr));
}
}
void end (void)
{
if (ctsr == ntsr-1)
return;
ctsr = ntsr-1;
currow = (ntsr < NROWS) ? ntsr : NROWS;
refresh ();
}
void home (void)
{
if (!ctsr)
return;
ctsr = 0;
currow = 1;
refresh ();
}
char *info (int row)
{
int i;
static char buffer [NCOLS+1];
unsigned segment = psps [row];
for (i = 0; i < NCOLS; i++)
buffer [i] = ' ';
buffer [NCOLS] = '\0';
buffer [0] = 'A';
buffer [1] = 'L';
buffer [2] = 'T';
buffer [3] = '-';
buffer [4] = peekb(segment, KEYOFS);
buffer [6] = 'T';
buffer [7] = 'S';
buffer [8] = 'R';
buffer [9] = ':';
i = SIGOFS+4;
while (peekb(segment, i))
buffer [6+i++-SIGOFS] = peekb(segment, i);
return buffer;
}
void refresh (void)
{
int index, _min, _row;
index = ctsr-currow+1;
_min = min(NROWS, ntsr);
for (_row = 1; _row <= _min; _row++)
{
v_gotoxy (column+1, row+_row);
v_setattr (attr [(currow == _row) ? 1 : 2]);
v_cputs (info (index++));
}
}
int scan (void)
{
char typemcb = BLOCMCB;
unsigned segment = 0x40;
do
{
if (peekb(segment, 0) == BLOCMCB) /* Found first MCB? */
if (peek(segment, 1) == segment+1) /* First MCB owns ... */
break; /* ... following segment */
if (++segment == 0xa000) /* Goto 640K segment ... */
return -1; /* ... even if less mem */
}
while (1);
ntsr = 0;
do
{
if ((~peekb(segment+1, SIGOFS) == 'T') &&
(peekb(segment+1, SIGOFS+1) == 'S') &&
(peekb(segment+1, SIGOFS+2) == 'R') &&
peek(segment, 1) == segment+1)
psps [ntsr++] = segment+1;
if (typemcb == LASTMCB || ntsr == MAXPSP)
break;
segment += peek(segment, 3)+1; /* Point to next MCB */
typemcb = peekb(segment, 0); /* Obtain MCB type */
if (typemcb != BLOCMCB && typemcb != LASTMCB)
return -1;
}
while (1);
return (ntsr) ? 0 : -1;
}
void up (int nlines)
{
int i, uplines;
if (!ctsr)
return;
v_setattr (attr [2]);
v_gotoxy (column+1, row+currow);
v_cputs (info (ctsr));
uplines = min(ctsr, nlines);
for (i = 1; i <= uplines; i++)
{
if (currow != 1)
currow--;
else
v_scroll (column+1, row+1, NCOLS, NROWS, SCROLL_DN,
1, attr [2]);
if (i == uplines)
v_setattr (attr [1]);
v_gotoxy (column+1, row+currow);
v_cputs (info (--ctsr));
}
}
#ifndef INCL_ISALPHA
#include "isalpha.C"
#endif
#ifndef INCL_ISDIGIT
#include "isdigit.C"
#endif
#ifndef INCL_KFETCH
#include "kfetch.C"
#endif
#ifndef INCL_VBORDER
#include "vborder.C"
#endif
#ifndef INCL_VCPUTS
#include "vcputs.C"
#endif
#ifndef INCL_VGETMODE
#include "vgetmode.C"
#endif
#ifndef INCL_VGETSHAPE
#include "vgetshap.C"
#endif
#ifndef INCL_VPAINT
#include "vpaint.C"
#endif
#ifndef INCL_VSCROLL
#include "vscroll.C"
#endif
#ifndef INCL_VSETATTR
#include "vsetattr.C"
#endif
#ifndef INCL_VSETSHAPE
#include "vsetshap.C"
#endif
#ifndef INCL_VSHADOW
#include "vshadow.C"
#endif
#ifndef INCL_VWHEREX
#include "vwherex.C"
#endif
#ifndef INCL_VWHEREY
#include "vwherey.C"
#endif
int xparse (int option)
{
int accum, digit;
if (option == 'R') /* RESET OPTION */
{
setrseg ();
column = 1;
srow = -1;
setcseg ();
return 0;
}
if (option == 'X') /* COLUMN OPTION */
{
if (!isdigit ((digit = parse ())))
{
_AH = 9;
_DX = FP_OFF("hotkey: digit expected after 'X'\r\n$");
geninterrupt(0x21);
return -1;
}
accum = digit-'0';
if (!isdigit ((digit = parse ())))
unparse ();
else
{
accum *= 10;
accum += (digit-'0');
}
if (accum < 1 || accum > (80-NCOLS-2))
{
_AH = 9;
_DX = FP_OFF("hotkey: column out of range ...\r\n$");
geninterrupt(0x21);
return -1;
}
setrseg ();
column = accum;
setcseg ();
return 0;
}
if (option == 'Y') /* ROW OPTION */
{
if (!isdigit ((digit = parse ())))
{
_AH = 9;
_DX = FP_OFF("hotkey: digit expected after 'Y'\r\n$");
geninterrupt(0x21);
return -1;
}
accum = digit-'0';
if (!isdigit ((digit = parse ())))
unparse ();
else
{
accum *= 10;
accum += (digit-'0');
}
if (accum < 1 || accum > (50-NROWS-2))
{
_AH = 9;
_DX = FP_OFF("hotkey: row out of range ...\r\n$");
geninterrupt(0x21);
return -1;
}
setrseg ();
srow = accum;
setcseg ();
return 0;
}
return -1;
}