home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
progmisc
/
nfsrc21.zip
/
SETKEYS.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-10-17
|
6KB
|
146 lines
; File......: SETKEYS.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
; Date......: $Date: 17 Oct 1992 16:27:42 $
; Revision..: $Revision: 1.1 $
; Log file..: $Logfile: C:/nanfor/src/setkeys.asv $
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
;
; $Log: C:/nanfor/src/setkeys.asv $
;
; Rev 1.1 17 Oct 1992 16:27:42 GLENN
; Leo cleaned up documentation blocks.
;
; Rev 1.0 16 Oct 1992 00:02:42 GLENN
; Initial revision.
;
; $DOC$
; $FUNCNAME$
; FT_SETKEYS()
; $CATEGORY$
; Keyboard/Mouse
; $ONELINER$
; Get array of keys redirected via the SetKey() or SET KEY
; $SYNTAX$
; FT_SetKeys() --> aKeyValues
; $ARGUMENTS$
; None
; $RETURNS$
; An array from 0 to n elements, where n is the number of keys that
; have been redirected via SetKey(). Each element in the array contains
; the Inkey() value of a key that has been redirected.
; $DESCRIPTION$
; Nantucket encourages Clipper programmers to write modular code -- black
; boxes that do not modify any global settings without resetting them
; on exit. In the past, this has proven cumbersome where SetKey() is
; concerned, because the only way to see if a key had been redirected
; was to call SetKey() and see if it returned NIL or a code block. To
; check every possible key value was unacceptably slow.
;
; This function attempts to alleviate this problem by returning an array
; that contains only those keys that have been redirected. It is
; substantially faster than the method mentioned above because it
; directly accesses Clipper's internal table of redirected keys.
;
; Some highly unorthodox programming techniques, not to mention rather
; strange use of Clipper internals, was necessary to make this function
; work. If this makes you uncomfortable, then don't use this function,
; you snivelling coward.
;
; $EXAMPLES$
; local aKeys := FT_SetKeys() // Get the key table
; local aBlox := {} // Create a parallel array
; local i
;
; for i := 1 to len( aKeys )
; // Nullify all redirections, while saving code block
; // for later restoration
;
; aadd( aBlox, setkey( aKeys[ i ], NIL )
; next
;
; // Do some stuff
;
; for i := 1 to len( aKeys )
; // Restore the redirections
;
; setkey( aKeys[ i ], aBlox[ i ] )
; next
; $END$
;
IDEAL
Public FT_SetKeys
VRefSize EQU 14
Counter EQU Word Ptr BP - 2
Extrn __RetNI:Far
Extrn __Keyboard:Far ; INTERNAL!
Extrn _ArrayNew:Far ; INTERNAL!
Extrn __Eval:Word ; INTERNAL!
Extrn __TOS:Word ; INTERNAL!
Extrn __cAtPut:Far ; INTERNAL!
Extrn __PutLN:Far ; INTERNAL!
Segment _Nanfor Word Public "CODE"
Assume CS:_Nanfor
Proc FT_SetKeys Far
Push BP ; Preserve BP
Mov BP,SP ; Set up stack reference
Sub SP,2 ; Allocate a local
Mov [Counter],0 ; Initialize it to zero
Mov DX,Seg __Keyboard ; Load segment of known symbol
Mov BX,Offset __Keyboard ; Load offset of known symbol
Add BX,1Bh ; Calc offset into code segment
Mov ES,DX ; Load segment register
Mov BX,[Word Ptr ES:BX] ; Lift address from machine code
Mov CX,[Word Ptr BX] ; Get size
LES BX,[DWord Ptr BX + 2] ; Get address of table
JCXZ @@Save ; If table empty, skip next part
@@Top: Mov AX,[Word Ptr ES:BX] ; Load key value
Or AX,[Word Ptr ES:BX + 2] ; See if it's null
JZ @@Bottom ; If so, skip it
Inc [Counter] ; Increment counter
Push [Word Ptr ES:BX + 2] ; Put key value on stack
Push [Word Ptr ES:BX]
@@Bottom:Add BX,4 ; Adjust offset
Loop @@Top ; Check next value
@@Save: Push [Counter] ; Put key count on stack
Call _ArrayNew ; Create Clipper array
@@Store: Cmp [Counter],0 ; Reached end yet?
JE @@Done ; If so, quit
Call __PutLN ; Create entry on eval stack
Add SP,4 ; Remove entry from CPU stack
Push [__TOS] ; Source VREF pointer on stack
Push [Counter] ; Element # on stack
Push [__Eval] ; Target VREF pointer on stack
Call __cAtPut ; Store array element
Add SP,6 ; Realign stack
Sub [__TOS],VRefSize ; Remove entry from eval stack
Dec [Counter] ; Decrement counter
Jmp Short @@Store ; Do next element
@@Done: Mov SP,BP ; Realign stack
Pop BP
Ret
Endp FT_SetKeys
Ends _Nanfor
End