Do-It-All Keyboard Enhancer
Table of Contents
INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . . . 1
REQUIREMENTS . . . . . . . . . . . . . . . . . . . . . . 1
FEATURES . . . . . . . . . . . . . . . . . . . . . . . . 1
Variable Size Keyboard Buffer . . . . . . . . . . . 1
Increased Key Repeat Rate . . . . . . . . . . . . . 2
Anti-skid Braking . . . . . . . . . . . . . . . . . 2
Screen Blanking . . . . . . . . . . . . . . . . . . 2
Repeat Characters Entered Through the Alt-Keypad . 2
Enter Graphics Characters With the Alt-Keypad . . . 2
Disable FASTBUFF . . . . . . . . . . . . . . . . . 2
RUN-TIME CONTROL KEYS . . . . . . . . . . . . . . . . . . . . 2
ALT-RIGHT SHIFT: Clear the keyboard buffer . . . . . . . 3
-MINUS: Set repeat rate slow . . . . . . . . . . . . 3
-PLUS: Set repeat rate fast . . . . . . . . . . . . . 3
-DEL: Turn off FASTBUFF . . . . . . . . . . . . . . . 3
-INS: Turn FASTBUFF back on . . . . . . . . . . . . . 3
COMMAND LINE SETUP PARAMETERS . . . . . . . . . . . . . . . . 4
/Bn : Set buffer size . . . . . . . . . . . . . . . . . 4
/Vn : Set screen blanking delay . . . . . . . . . . . . 4
/Dn : Set repeat delay . . . . . . . . . . . . . . . . 5
/F : Select fast repeat rate . . . . . . . . . . . . . 5
/S : Select slow repeat rate . . . . . . . . . . . . . 5
SPECIFICS . . . . . . . . . . . . . . . . . . . . . . . . . . 5
HOOKS . . . . . . . . . . . . . . . . . . . . . . . . . 5
09H : Keystroke . . . . . . . . . . . . . . . . . . 6
(16H : Keyboard I/O) . . . . . . . . . . . . . . . 6
(08H : Hardware Timer Interrupt) . . . . . . . . . 6
1CH : Get Control on Timer Tick . . . . . . . . . . 7
10H : Video I/O . . . . . . . . . . . . . . . . . . 7
THE SOURCE CODE . . . . . . . . . . . . . . . . . . . . 8
INT 9 - KEYSTROKE . . . . . . . . . . . . . . . . . 8
Setup . . . . . . . . . . . . . . . . . . . . 8
Video counter . . . . . . . . . . . . . . . . 9
Command Key Check . . . . . . . . . . . . . . 9
FASTBUFF on/off . . . . . . . . . . . . . . . 9
First Alt-Key Break Check . . . . . . . . . . 10
Check for Clear Key Combination . . . . . . . 10
Call Old Interrupt Handler . . . . . . . . . . 10
CTRL-BREAK Check . . . . . . . . . . . . . . . 10
New Character Detected . . . . . . . . . . . . 11
PUT CHARACTER INTO OUR BUFFER . . . . . . . . . . . 11
Last Character . . . . . . . . . . . . . . . . 11
Repeat Delay . . . . . . . . . . . . . . . . . 11
Increment Tail Pointer . . . . . . . . . . . . 11
Turn the repeat function on . . . . . . . . . 12
INT 10 - VIDEO I/O . . . . . . . . . . . . . . . . 12
Reset Blanking Counter . . . . . . . . . . . . 12
Check if Video Disabled . . . . . . . . . . . 12
Function FAH . . . . . . . . . . . . . . . . . 12
INT 1C - TIMER TICK . . . . . . . . . . . . . . . . 13
Check if FASTBUFF is on . . . . . . . . . . . 13
Decrement Blanking Counter . . . . . . . . . . 13
Video Blanking Check . . . . . . . . . . . . . 13
Update BIOS Buffer . . . . . . . . . . . . . . 13
Repeating Keys . . . . . . . . . . . . . . . . 13
UPDATEBIOS . . . . . . . . . . . . . . . . . . . . 13
Check FASTBUFF Buffer . . . . . . . . . . . . 14
Transfer to BIOS . . . . . . . . . . . . . . . 14
Minimum Buffer Size . . . . . . . . . . . . . 14
REPEATING KEYS . . . . . . . . . . . . . . . . . . 14
Set Repeat Rate . . . . . . . . . . . . . . . 14
Anti-Skid Check . . . . . . . . . . . . . . . 14
Repeating the Key . . . . . . . . . . . . . . 15
INITIALIZATION . . . . . . . . . . . . . . . . . . 15
BYE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
REVISIONS . . . . . . . . . . . . . . . . . . . . . . . . . . 17
v2.3: David Steiner, March 15, 1989 . . . . . . . . . . 17
v2.2: Toad Hall Tweak, 2 Mar 89 . . . . . . . . . . . . 17
v2.1: Toad Hall Tweak, 23 Feb 89 . . . . . . . . . . . . 17
The only thing you really need to know in order to use FASTBUFF
is that to install it you type FASTBUFF and hit the ENTER key.
To see the results just hold down a key and watch how fast it
goes. If you run into problems with a program that doesn't like
FASTBUFF then you may want to look over this documentation a
Even if you're not entirely sure you like the idea of such a
keyboard enhancement program, at least give FASTBUFF a trial run.
After all, its a free program. You will quite likely find it
frustrating to go back to the normal repeat rate and buffer size.
Version 2.0 is a fairly large improvement over version 1.0, even
though this one has been released fairly quickly after the first.
The only bug fix was related to typing in characters via the
numeric keypad. It seems that the repeat function always ended
up set, and wouldn't stop till you hit another key.
FASTBUFF was written on an IBM XT compatible computer. It should
work with true IBM PC's just fine. I've also tested it on AT
compatibles, and it seems to work OK. The video blanking works
for CGA and monochrome systems, but not EGA. I doubt it will
work for other video cards either. I'll try to provide support
for them at a later date when I have time. If you don't have a
video card that is supported, it is best to disable this
As far as memory is concerned, FASTBUFF only eats up 1500 bytes
when its using a 100 character buffer. Even if you set the
buffer as large as it will go (269 characters) FASTBUFF still
only take up about 1800 bytes.
As usual, there are some restrictions on what order you load
FASTBUFF. Although it is a well-behaved resident program you
still get the best results if you load it early. This has to do
with who "hooks" which vectors and will be discussed below in
more detail. Some programs, however, are very low-level and
should be loaded before FASTBUFF. Such programs include the
keyboard drivers supplied with MS-DOS (KEYxx.COM).
Variable Size Keyboard Buffer:
FASTBUFF takes control of the keystroke interrupt in order
to allow you to set the size of buffer you like. The
default is 100 characters, but may range from 25 to 269
Increased Key Repeat Rate:
By using the timer interrupt we are able to modify how fast
keys are repeated. When FASTBUFF is activated you may
select between a repeat rate of 18 or 36 characters per
second. Unlike most key quickeners that I've seen, FASTBUFF
has a fairly smooth repeat rate even in its fast mode. Note
that you may also select the normal repeat rate by turning
Given a large buffer and fast repeat rate you could get way
ahead of your application when holding a key down. FASTBUFF
uses a simple but effective method of preventing this: it
doesn't put repeated characters into the buffer until the
application program is ready (i.e. the buffer is empty).
If you leave your computer unattended for over fifteen
minutes FASTBUFF will automatically blank the video screen
in order to avoid "burning" characters into the display
screen. The screen may be restored by pressing any key.
Repeat Characters Entered Through the Alt-Keypad:
The IBM will allow you to enter characters by holding the
ALT key down and typing the ASCII character number on the
numeric keypad. When you release the ALT key the character
is inserted at the cursor position. FASTBUFF also provides
a method of repeating the key entered this way.
Enter Graphics Characters With the Alt-Keypad:
Some of us poor folks with IBM compatibles have a BIOS that
gets confused when entering graphics characters via the
keypad (character numbers over 127). FASTBUFF takes control
of this function and returns these characters correctly.
This fix also pertains to compatibles that do not return the
normal scan code (0) for these characters.
It is possible that you may need to use a program that
doesn't seem to like FASTBUFF. To account for this
possibility you may turn off the FASTBUFF functions in order
to use these programs. After leaving the conflicting
application, you may re-enable FASTBUFF again.
RUN-TIME CONTROL KEYS
While FASTBUFF is resident you have several options for the way
it controls your keyboard. First we'll cover the option for
clearing the FASTBUFF keyboard buffer:
ALT-RIGHT SHIFT: Clear the keyboard buffer
You may clear the typeahead buffer by pressing the ALT and
RIGHT SHIFT keys simultaneously. This clears anything in
the buffer, even if you've already hit the ENTER key. This
function is not active when FASTBUFF is turned off.
The rest of the keys are entered by pressing keys while holding
down the FASTBUFF command key. This key has been chosen to be
the "5" key located on your numeric keypad, in an effort to clash
with as few other resident programs as possible. I will denote
this key as  from here on out. You must also note that this
key is distinct from the "5" key located in the top row of the
-MINUS: Set repeat rate slow
By pressing the  and the "-" key located right next to it
you may set FASTBUFF to use its slower repeat rate (18
characters per second). Note that this is still somewhat
faster than the normal repeat rate. Most of the time this
mode will also produce a "smoother" repeat.
-PLUS: Set repeat rate fast
The default setting for FASTBUFF is the fast repeat rate (36
characters per second). However, this is too fast for some
applications, so you may switch between the fast and slow
modes to suit your needs.
-DEL: Turn off FASTBUFF
This version of FASTBUFF has been rewritten to conflict with
as few other programs as possible. You shouldn't find too
many programs that will require you to turn FASTBUFF off.
On the other hand, you may occasionally wish to reduce the
keyboard buffer and repeat rates to the normal values and
this switch allows you to do just that.
-INS: Turn FASTBUFF back on
If you've turned off FASTBUFF, you can re-enable it by
pressing these keys simultaneously.
COMMAND LINE SETUP PARAMETERS
I've tried to set the defaults for FASTBUFF the way most people
will like them. However, if there is something you would like
different there are a few startup values you may change. To do
this you may enter setup codes on the command line after the file
name. For example:
would set the buffer to 255 characters, the video blanking off,
the character repeat delay to about a half second and the repeat
rate to 18 characters per second (FASTBUFF's slow repeat).
Each parameter consists of a slash "/", the parameter letter and
finally a number, if one is required. These may be entered in
any order, and even repeated. When a parameter is repeated the
rightmost one takes precedence.
FASTBUFF will not be installed if an invalid parameter is
entered, instead you will get a help screen. You may get this
help screen at any time by typing:
The help screen provides information on both the command line
parameters and the run-time command keys.
/Bn : Set buffer size
If you can actually type fast enough to fill the default
buffer you may wish to select a larger one by using this
parameter. Valid sizes are from 25 to 269. Note that
FASTBUFF will accept numbers larger than 269, but the value
actually used will be seemingly random.
/Vn : Set screen blanking delay
The amount of time FASTBUFF will wait for some form of input
or screen I/O before blanking the screen may be set with
this parameter. Valid numbers range from 0 to 60 minutes.
Again, larger numbers may be entered, but will produce delay
times ranging from 1 to 60 minutes anyway. Setting the
blanking delay to zero will disable it.
The video blanking has been tested with CGA, monochrome
(Hercules also) and EGA cards. It works fine with all
except the EGA. If you have this type of video card, or
others not listed, it is suggested that you disable screen
blanking just to be safe. When I get some time and some
more references I'll put together another version that
supports other cards.
/Dn : Set repeat delay
This parameter sets the amount of time (in timer clicks) a
key must be held before it is repeated. The default setting
is 5 clicks, which translates to about a quarter of a
second. I believe the BIOS repeat delay is somewhere around
9 (a half second) and you may prefer that delay.
/F : Select fast repeat rate
Actually, there isn't really any reason for this option
since the default setting is fast. I included it mostly for
consistency. The fast repeat rate is 36 characters per
/S : Select slow repeat rate
This parameter sets the repeat rate to FASTBUFF's slower
rate, 18 characters per second. The BIOS repeat rate seems
to be about 9 char/second, so FASTBUFF is still quick, even
in its slow mode. Note that setting the fast or slow repeat
rate only affects the startup mode, the repeat rate may
still be switched at any time by using the run-time commands
Now we will start getting a little more specific about what each
of these functions do. This may (or may not) be helpful for
those of you mucking about in the source code.
If you've had your computer for long, you've probably already
heard too much about hooking vectors and related quirks of the
IBM. Sorry, but FASTBUFF is something of a "system" program
rather than an "application" and hooking is a requirement (wipe
that smirk off your face).
In order to get all of the FASTBUFF features we only had to hook
into three interrupt vectors, although we considered a few
others. Here is a list of the vectors and why we use (or didn't
09H : Keystroke
We had to take over this vector in order to steal characters
from the BIOS input buffer and put them into ours as they
were typed. Well, as long as we've taken over the keystroke
interrupt why not make our control key something that isn't
likely to conflict with other programs (like the five on the
Hey, we can fix that silly bug with our BIOS that won't let
us enter graphics characters on the keypad too.
(16H : Keyboard I/O)
Well, now we need to be able to get those characters back
out of our new buffer, since we've stolen them from the
BIOS. We could take over this interrupt and return
characters from our buffer whenever the system asks for
keyboard input, but it turns out that this isn't a good
The problem is that there are just too many programs that
access the BIOS keyboard buffer directly, without consulting
the system. Another, less obvious problem, is that if we
completely take over parts of this interrupt, we don't pass
control on to the next program that hooked this vector.
This is becomes a problem when such programs are loaded
If you've already seen FASTBUFF v1.0 you know that this was
the original design. Version 2.0 uses the method described
under interrupts 08 and 1C, and is much less likely to cause
problems with other programs.
(08H : Hardware Timer Interrupt)
Lets see... If we don't use interrupt 16 to return
characters, what are we going to do? Well lets try checking
once in a while to see if the normal BIOS buffer is full and
if not insert characters from our buffer into the BIOS
buffer. The only reliable way to do this is to hook into
the timer click interrupt. This allows us to perform this
check 18.2 times per second (how often this interrupt is
generated by the system).
Well, we have the right notion, but we really shouldn't use
the hardware interrupt for this. The problem is that the
system performs important actions every time this interrupt
is issued, and if we take control first we will slow down
its response. The "proper" method uses the next interrupt.
1CH : Get Control on Timer Tick
This interrupt was provided by the system to allow actions
of just the type we want. If we're careful we can insert
our code and pass control on to other programs that hook
this vector with no problems.
Now, we already know that we are going to be using this
interrupt to update the BIOS buffer, so as long as we're
here let's add another function that has a reasonable low
Lets set up a counter to keep track of how long its been
since the last screen I/O operation was performed. If the
computer sits unattended for too long we can then blank the
screen to avoid damaging the monitor. To do this right
we'll have to reset the counter every time a key is pressed
or something is written to the screen, which means we'll
have to hook one more vector.
10H : Video I/O
To reset our screen blanking cursor when a key is pressed is
no problem, we can just insert a few lines of code in our
interrupt 9 handler. However to detect if something is
written to the screen we must take over this interrupt.
When a program is accessing the video in the "proper" way it
will use this function interrupt to make changes to the
screen. Therefore we should reset our screen blanking
counter whenever this interrupt is used.
Again, there are some problems. For example, many programs
write to the screen directly and never bother the system
with an interrupt 10 call. For the video blanking this
really isn't very serious since the worst that could happen
is that the screen gets blanked when there really is some
activity. All the user will have to do is type any key and
the screen will be restored by our interrupt 9 reset
Finally, we decide to add one more frill. We'll give
FASTBUFF some way to indicate that it is present if someone
asks nicely. This will enable us to detect if FASTBUFF is
present when the program is executed and abort the
installation in order to avoid having two copies in memory.
We will add this feature as part of our interrupt 10 handler
for two reasons. The reason for choosing an interrupt to
perform this function is that we don't know where in memory
a previous copy of FASTBUFF might be located, so we need
this alternate method for detecting it. We choose interrupt
10 to perform this function since it is the only one we have
hooked that normally accepts input parameters and returns
Note that in the above list the interrupt vectors listed in
parenthesis are not actually used by FASTBUFF, they are listed
only as alternative considerations.
Well that list should give you a feel for how FASTBUFF works. Of
course, I didn't actually design it in that manner, I used a much
more professional approach (I wrote version 1.0 and started
discovering bugs a couple of days later).
THE SOURCE CODE
In this section I'll go over what each interrupt handler in the
source code does, in a general manner. I won't cover the
initialization code, other than detecting if FASTBUFF is
installed, since that stuff is small potatoes.
If you don't fully understand interrupt vectors yet, there isn't
much I can help you with here. There are entire books written on
INT 9 - KEYSTROKE
The first thing I should note here is how and when this interrupt
is called. This interrupt is issued every time a key is pressed
or released. The keyboard returns the scan code (a byte) through
one of the input ports to let the computer know which key it was.
The scan codes that have meaning to us are defined in the equates
set in the first section of the source code. These codes are for
the "make" signals, or when the key is depressed. The "break"
code, or when the key is released, can be calculated by setting
the high bit of the make code (code+80H).
Another note is that FASTBUFF keeps all of its status information
in a single byte. We use the bits in this byte (switches) to
indicate certain conditions in FASTBUFF. The bits will be
accessed by anding and oring the status byte with masks that we
set in the equates section of the code.
When we enter this interrupt there are a few things we must
do along the lines of resetting FASTBUFF. The first such
item is turning off our repeat switch bit (repmask). This
is done so FASTBUFF won't continue to repeat a character
after another key is pressed.
Next we set the ES register so we can use it to access the
BIOS data used by the rest of the system. After doing this
we reset the BIOS break detection bit. We do this so we can
test it again after the old interrupt 9 call in order to see
if we need to clear our buffers.
The next item we should take care of is resetting our video
blanking counter. If this interrupt is called the user must
have typed some key, so we should start the blanking
A related check is to see if the video is currently shut
off. If the user was gone for a while and the screen was
shut off we now need to turn it back on since they are
Command Key Check:
Next we need to see if the command key is currently pressed.
We keep track of this by setting a bit (ctrlmodemask) in our
FASTBUFF status byte when the  key is pressed. We leave
this bit set until we receive the scan code indicating that
the  key was released.
If the command mode bit is set we then need to see if second
key in a control key combination was pressed. If one of the
two combinations were pressed for turning FASTBUFF on or off
then we need to set the appropriate bit in our status byte
(fbmask). If FASTBUFF is turned on or off we need to clear
our keyboard buffer just to be certain there aren't any
problems caused by the switch.
Note that even when we intercept these command keys that we
still pass control on to the old interrupt handler, even
though we ignore any characters it may have tried to put in
the BIOS buffer. This pass is done to minimize the
possibility of FASTBUFF clobbering another resident program.
Next, if FASTBUFF is on, we need to check for the key
combinations that are used to set the key repeat speed. We
don't perform this check when FASTBUFF is off, again to
minimize clashing with other resident utilities.
At this point we have taken care of all the required
resettings and checks so we may finally check if FASTBUFF is
active. If FASTBUFF is currently turned off we may safely
make the call to the old interrupt 9 handler and exit the
First Alt-Key Break Check:
One of the things FASTBUFF is supposed to do is take care of
the Alt-keypad entries and make sure they are returned in
the standard IBM BIOS format. The first step in this
direction is to watch for the scan code that indicates that
the ALT key was released.
If this code is detected we will steal a copy of the
character number created by the BIOS. This character is
stored in a byte in the BIOS data area (BIOSaltbuff). We
need to store it now since it will be zeroed when the call
to the old interrupt 9 handler.
Check for Clear Key Combination:
Another control-type key we need to check for is the
CTRL-RIGHT SHIFT clear buffer combination. If this key is
detected (while FASTBUFF is active) we need to clear out the
Call Old Interrupt Handler:
If we make it this far without encountering a control key we
finally call the old keystroke interrupt handler. We are
doing this for two reasons: its a good idea to pass control
on to the old one and there is no reason to duplicate the
BIOS code that translates the keyboard scan codes into ASCII
Something that I'll cover in more detail later is the reason
for setting a bit in our status byte that indicates we are
calling the old interrupt 9 handler.
After calling the old BIOS handler we can tell if a
character was entered by whether or not the BIOS tail
pointer has moved. After storing this character and
checking for a new character we restore the old value of the
BIOS tail pointer. This effectively removes the character
from the BIOS buffer.
We now need to check the CTRL-BREAK bit again to see if that
key combination was pressed. If so we have to clear the
buffers and output a dummy character. The dummy character
is done to emulate the way the normal BIOS returns a
New Character Detected:
If a new character was input we need to remove it from the
BIOS keyboard buffer and insert into ours. Before we insert
the character we want to check again to see if it was
entered via the keypad. If so we must first fix the
character code to be inserted.
The fix for these characters simply consists of retrieving
the character we saved earlier and forcing it into the
standard format. The standard format is just the ASCII code
in the low byte and a zero in the high byte. If your system
already does this correctly, then the fix doesn't hurt
The actual insertion of the character into our buffer will be
covered in the next section.
PUT CHARACTER INTO OUR BUFFER
This check is done to make sure that the character just
entered did not come from the standard BIOS repeat function.
If the character input matches the last one typed it may be
assumed that the scan code came from the standard repeat and
we will ignore it. The character is ignored in order to
avoid a repeat speed that looks jerky.
Note that we may assume that a character that matches the
lastchar value is from the standard repeat since we would
see the break scan code if the key was released.
There are two variables that must be set for use later by
the repeat function. The first is the one mentioned above.
We need to keep track of the last character entered for use
by the repeat function. Since this is a new character we
set the counter for the repeat delay to its starting value.
Increment Tail Pointer:
The next step is to increment the tail pointer on our
buffer. If this incremented value matches the head pointer
then the buffer is full and we need to beep to tell the
Turn the repeat function on:
Since we detected a new typeable character we need to turn
the repeat function back on. This tells the interrupt 1C
handler to repeat the character when it is called later.
There is another modification that FASTBUFF makes to the
character repeat function. If the character was entered
through the keypad its scan code will be zero. If this is
true and the user is currently holding down the LEFT SHIFT
key we will allow the character to repeat until the LEFT
SHIFT is released.
INT 10 - VIDEO I/O
Reset Blanking Counter:
The first thing to do is reset the screen blanking cursor.
If the program performs any video output then we assume that
the counter should be reset.
Check if Video Disabled:
After resetting the counter we still need to make sure the
video is still on. If it was disabled earlier the video
active bit will have been cleared to let us know that we
need to restore it.
A final addition to this interrupt will be a way for
FASTBUFF to indicate that it is resident. This will allow
us to avoid loading two copies of FASTBUFF.
All we need to do to implement this is to check if the AH
register contains FAH. If it does we will return 00FAH in
the entire AX register to let the calling program know we're
Unless there is some other application resident that doesn't
behave properly this shouldn't cause a problem. The BIOS
will normally ignore any function request it doesn't
recognize. The likelihood of some other resident program
using function request FAH is pretty low.
INT 1C - TIMER TICK
Check if FASTBUFF is on:
The first thing for this interrupt handler is to make sure
FASTBUFF is currently active. If it isn't active then we
aren't supposed to be doing anything here.
Decrement Blanking Counter:
If the program is active then we need to decrement the
counter that lets us know when the screen is to be blanked.
Video Blanking Check:
When the counter reaches zero we still have to make sure
that the video blanking option is enabled. If the screen is
supposed to be blanked then we call the routine that does
this and clear the bit that indicates the screen is active.
Update BIOS Buffer:
As mentioned earlier we aren't using the keyboard i/o
interrupt to return characters to the system. We chose this
method to improve compatibility with other programs.
The updateBIOS procedure will be covered in the next
section, but for now we should note the check with the
oldint9mask. This check is done to make sure we aren't
currently making a call to the old interrupt 9 handler. If
we were to try to add characters while BIOS is trying to
take them out we will occasionally lose a character or two.
We set our own flag for this because the interrupt flag will
be reset from within the old int 9 handler if we try to use
the CLI instruction.
If the repeat bit is still set from the interrupt 9 call
above then we need to repeat the character stored as the
lastchar. This procedure will be described below.
This method is used to increase compatibility with other programs
that may do low-level keyboard i/o. Using this method we are
always transferring characters into the BIOS buffer and letting
the system to the retrieval for us. This also allows other
programs to access the BIOS buffer directly in order to get
Check FASTBUFF Buffer:
Of course the first step in copying characters from our
buffer to the BIOS buffer is to make sure we have something
Transfer to BIOS:
If there are characters to copy then we move as many as we
can into the BIOS buffer. We must, however, keep in mind
that the old BIOS keystroke handler expects to put input
characters into its buffer. For this reason we must keep an
extra space open for its use when we do the update,
otherwise the BIOS routine will just beep at us when we call
Minimum Buffer Size:
Now that you know how this works I can explain why the
minimum buffer size is set at 25. In order to avoid a lot
of special cases we need to make the minimum at least 15 (14
from the BIOS and 1 in our buffer). However, since we need
to occasionally expand our buffer before the BIOS update
this is not a good idea, FASTBUFF would then beep if only
two characters were received in quick succession.
The minimum of 25 allows 14 characters of BIOS storage and
16 in ours. It is nearly impossible to type characters fast
enough to fill our buffer before we get a chance to transfer
some of them to the BIOS buffer.
Set Repeat Rate:
The first thing that must be done after we deciding to
repeat a key is to reset the repeat count to 1. This allows
us to check for a repeat on the next tick again. Back in
the character input routines we set the repeat count to the
starting delay, which defaults to 5 clicks.
FASTBUFF uses a very simple check to make sure it is not
going too fast for the application being used. It just
checks the BIOS buffer, and if its empty then we repeat the
character, if not we can just wait till the next click and
Since we just checked to make sure the buffer was empty, and
the minimum buffer size is 25 we know there won't be any
problems with filling the buffer either. This allows us to
repeat the character without bothering to check if the
Repeating the Key:
Next we retrieve the character to be repeated and put 1
(slow repeat) or 2 (fast) copies of it into the BIOS buffer.
Note that we must insert more than one character per click
to achieve repeat rates faster than 18 characters per
As mentioned above, all I am going to cover here is the check to
see if FASTBUFF is already installed. The method was described
above anyway, but I'll mention it again just for the heck of it.
Since we don't know where in memory FASTBUFF will be installed we
need some way other than just looking for a certain string we may
have placed in the code. One approach using this method would be
to use the DOS call to get the interrupt address for one of the
vectors FASTBUFF hooks and then look for such a search string
assuming that was the code segment for a previously installed
FASTBUFF. The problem with this is that there may be another
application installed later that hooks that vector also.
Instead we will allow our interrupt 10 handler an extra function.
When we send an function FAH request, FASTBUFF will send back
00FAH in the AX register. If we don't get this code we should be
able to assume that FASTBUFF is not already present on the
Another note on the initialization process is that we don't
enable FASTBUFF until well after we have initialized its
variables and hooked all the required vectors. This is done to
prevent someone from typing ahead during the FASTBUFF
initialization and only having part of the required routines to
handle the input.
Finally we print the initialization message well before hooking
any vectors or enabling FASTBUFF. This is because we are using a
DOS call to write out output to the screen and the user can hit
CTRL-BREAK during this message and halt the program. If this
were done after the vectors are hooked and before FASTBUFF
terminates and remains resident the system will hang as soon as
the next program is run, since the interrupt handlers will be
overwritten at that time.
Well I hope someone finds this program useful. Sorry I get write
such long documentation, but I get started and then hate to leave
If you find any bugs, or have any additional information you
think I'll find useful please let me know:
[D.STEINER] on GEnie
2035 J Apt.6
Lincoln, NE 68510
My thanks to Toad Hall and Keith Peterson for taking interest in
FASTBUFF and helping to improve it. Toad Hall produced a v2.1
and v2.2 based on the FASTBUFF v2.0 code. I had released
versions later than 2.0, but it was a simple task to just
incorporate my revisions into a v2.3 based on their upgraded
As far as I know the changes were mostly in the area of speeding
up some of the interrupt handlers and making the code a bit
smaller. I agree that my use of ES: was clumsy (ouch, that hurt)
but I didn't know better at the time. These changes may affect
the above discussions concerning the source code, but I haven't
the time to straighten that out.
Revisions are not reflected in the above discussions on the
source code. This is most notable in the change from using
timer tick interrupt 08H instead of 1CH.
v2.3: David Steiner, March 15, 1989
Changed from using the software timer tick interrupt (1CH)
to using the hardware timer interrupt (08H). I really
didn't want to do this, for reasons mentioned above, but
there are too many programs that clobber the software
IBM BASIC is a good (bad?) example of this. It hooks the
software timer interrupt and doesn't pass control on to
resident programs that were using it. This causes FASTBUFF
to lock up the keyboard while it is active (you could regain
control by pressing -DEL, but that was a pain). Since
BASIC programs are so bountiful I decided I had better fix
v2.2: Toad Hall Tweak, 2 Mar 89
- Keith Petersen detected DSZ serial port errors when FASTBUFF
was installed and DSZ was running at VERY high (19200 baud)
Suspect we're grabbing interrupts too often or too long.
Tweaking to reduce CLI periods and ANY other delays.
- Removed a bunch of v2.0 code I'd commented out in v2.1
(since v2.1 seems to be working all right).
v2.1: Toad Hall Tweak, 23 Feb 89
- General tightening
- Much more use of AX vs. other regs
- Described a Page40 segment to permit faster BIOS variable
- Now using DS: instead of ES: to address BIOS variables.
(Eliminate all those clumsy, slow, bulky ES: overrides.
- FATAL error when new interrupt svcs call or jump to the old
interrupt vectors! Author didn't address the saved vector
(oldint9, etc.) as CS: , donno HOW this sucker EVER worked!
- Tightened up installation procedure:
- Uses runtime variables rather than installation variables.
- If error, terminates with proper Svc 4CH, Int 21H.
- Now freeing environment variable before going TSR
- Rounding up TSR program/data size to nearest paragraph
before going TSR.
- Reduced .COM file about 1Kb. Runtime memory requirements:
- v2.0 1504 bytes, 2 blocks
- v2.1 1296 bytes, 1 block
.. not too shabby.