                           FKEY/CMD
               A public domain program from the
      Christian Computer Users Association TRS-80 Library
                    Provided by Bob Grommes
       1733 Eastern S.E., Grand Rapids, Michigan  49507

     This machine-language utility runs under Model 4 TRSDOS
Version 6 and allows you to change the code values generated by
the three function keys.  It will redefine any or all of the
function keys, both shifted and unshifted, and/or display the
current settings of the keys.  This has many practical uses in
any program that uses the standard keyboard device (*KI) to
scan the keyboard; for example, when writing BASIC programs, if
you make much use of the carat symbol (used for
exponentiation), you will find it easier to define a function
key to that particular symbol rather than to constantly press
<CLEAR> and <;> at the same time.  Commonly used Disk Scripsit
control keys such as <CLEAR> <S> could be generated by a single
function key, often saving one or two keystrokes, as well as
being less awkward besides.
     The command syntax for FKEY is as follows:

                             FKEY

. . . without any parameters will simply display the current
settings of the unshifted function keys.

  FKEY (F1="[",F2="]",F3="^",S1="{",S2="}",S3="|")
  FKEY (F1=91,F2=93,F3=94,S1=123,S2=125,S3=124)
  FKEY (F1=X'5B',F2=X'5D',F3=X'5E',S1=X'7B',S2=X'7D',S3=X'7C')

. . . the above three commands produce identical results.  The
F1, F2 and F3 parameters define the unshifted function keys;
the S1, S2 and S3 parameters define the shifted function keys
(that is, <SHIFT> <F1>, <SHIFT> <F2>, etc.).  Each parameter
can be defined as a quoted string, a decimal value or a hex
value in X'nn' format.  You can mix any combination of string,
decimal or hex values on a command line, and the order of the
parameters isn't important.  Of course, you don't have to use
all of the parameters either, only those you want to.

                        FKEY (DEFAULT)

This command will reset the function keys to their default
values.
     Since FKEY executes entirely within the library overlay
memory region, it is callable from any program that allows you
to invoke TRSDOS library commands.  Often, you will have to do
this by using the TRSDOS command RUN.  For example, you can run
FKEY from BASIC with the following command:

                SYSTEM "RUN FKEY (parameters)"

     Please note that you cannot use FKEY to allow a function
key to emulate the SHIFT - @ function of PAUSE.  Since TRSDOS
specifically scans SHIFT and @ to detect the PAUSE condition,
even though a function key may generate the code value of
X'60', it will NOT be detected as PAUSE.
     [The following additional comments on FKEY/ASM were
provided by Bob Grommes.]
     Just a few technical notes on FKEY and TRSDOS 6 assembly
language coding in general:
     The whole subject of Supervisor Calls (SVC's) used in
TRSDOS 6 and other Model 4 DOS's may be a little unfamiliar to
those of us accustomed to Model I/III assembly language
practices.  FKEY, like almost all machine code for the native
Model 4 mode, makes extensive use of SVC's.  Fortunately they
are quite simple to understand and have some real advantages to
the programmer.  Consider the following code:

                Model III:

                GET     EQU     013H

                        LD      DE,FCB
                        CALL    GET

                Model 4:

                @GET    EQU     3

                        LD      A,@GET
                        LD      DE,FCB
                        RST     40

     Both of these routines input a single byte from a device
or file pointed to by DE.  Both take up 6 bytes of memory, and
both take 8 machine cycles to execute.  Why use a SVC then?
Well, it allows routines within the operating system to "have
legs", and move around freely during different releases of the
DOS, without us programmers having to chase them around.  The
bad news is that all user SVC's in TRSDOS 6 use the RST 40 (or
RST 28H) instruction.  This means there is not a lean, mean
subroutine sitting right at 28H.  It means there's a jump
vector to a routine that looks at the accumulator, sees what
SVC you want, accesses another table of vectors and THEN jumps
to the appropriate subroutine.  This means more overhead than
some CALLs.  On the other hand, many routines in the familiar
Model III ROM were accessed via vectors and used various
pointers to pointers to pointers also.  Some also needed fairly
involved stack setup to properly invoke as well.  So the extra
overhead may not be that much of a real problem when you look
at the big picture and the Model 4's faster clock speed.  In
any case, despite the relative merits of SVC's, we have to deal
with them, because they're there!
     The SVC's used in FKEY have the following functions:

@DSPLY  Display a message string
@PARAM  Parse the command line for any parameters in
        parentheses
@GTMOD  Get the address of a device driver given the device
        name
@HEX8   Convert a one-byte value to ASCII Hex representation
@LOGOT  Same as @DSPLY except the message is also sent to the
        JOBLOG, if active.

     @DSPLY should be very easy to grasp as it's just a
familiar "display a string pointed to by HL" routine.  @LOGGER,
not used in this program, does the same thing except the
message goes to the joblog, if it's active.  @LOGOT, which IS
used here, is the same as using @DSPLY followed by @LOGGER.
You should use @LOGOT instead of @DSPLY for error messages,
because if the user had joblog active, he will want any error
messages to show up there as well as on the display.
     @PARAM, the parameter scanner, is a real code saver since
it will do almost any command line parsing you can imagine with
a single call.  The only overhead is your parameter table
(represented in FKEY by PRMTBL$) which tells @PARAM what your
valid parameters are and whether or not abbreviations are
legal, etc.  A detailed explanation of @PARAM is beyond the
scope of this article but it's well worth your taking the time
to study the Technical Reference Manual, which shows how a
parameter table is set up.  It's not as exotic as FKEY makes it
look, it's just that the programmer here was using some of his
own personal short-hand short-cuts and the features of the EDAS
assembler package to produce the table.
     Anyway, the theory behind FKEY is simple:  First, find the
data area of the keyboard driver, a task easily accomplished
with @GTMOD.  The DE register is pointed to the two-character
module name KI.  After issuing the @GTMOD SVC, HL will contain
the entry address of the module, which we throw away because we
don't need it.  DE, on the other hand, will point to the start
of the "data area" of the *KI driver.  Just what is it that we
find here?  According to what documentation I have, it looks
like this:

DE ==>    the last character entered
DE+1 ==>  Contains the repeat time check which is the system's
          timer value that when reached will result in a repeat
          of the last character if the keycode scanned has not
          changed.
DE+2 ==>  Contains the waiting time in timer units that must
          transpire before a character can initially be
          repeated.  This value is set by the SETKI (Wait=nn)
          library command.
DE+3 ==>  Contains the repeat rate in timer units.  Set by
          SETKI (Rate=nn).
DE+32 ==> The function key table (on Model 4 and 4P only, may
          be elsewhere on the MAX 80 and other machines on
          which TRSDOS 6 is implemented).

So at this point, FKEY just adds 32 to DE and stuffs whatever
value(s) you supply on the command line into the function key
code table.
     An interesting point is borne out here for anyone using
the Model 4 function keys.  Since it's possible for these keys
to be redefined, you may want to add initialization code to any
program that uses these keys which will save whatever is in the
function key table, insert whatever values your program expects
(even the default values) and then, upon termination of your
program, restores whatever was in the function key table at
entry.  This would prevent a user from inadvertently locking
himself out of certain functions of your program or even
causing unexpected things to happen when pressing the function
keys!
.
...................................
.                                 .
.    Downloaded in 1990 from:     .
.                                 .
.      ********************       .
.      *     8/N/1 #1     *       .
.      *   904/377-1200   *       .
.      * Gainesville, FL  *       .
.      * Guy Omer - SYSOP *       .
.      ********************       .
.                                 .
. Software support for the TRS-80 .
...................................
