home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c017 / 2.ddi / GETKEY.ZIP / GETKHA.ASM < prev   
Encoding:
Assembly Source File  |  1990-04-09  |  10.1 KB  |  251 lines

  1. LISTING 3:GETKHA.ASM
  2. ; GETKHA.ASM - This assembler module is designed to link with a C module
  3. ; to effect low level getkey hook management.
  4.  
  5. DGROUP    group    _DATA,_BSS
  6.  
  7. _DATA    segment word public 'DATA'
  8.  
  9. extrn    _poll0_hook:word        ; Tell the assembler that the
  10. extrn    _filter0_hook:word        ; hook pointers are actually
  11. extrn    _poll1_hook:word        ; declared within the application.
  12.  
  13. _DATA    ends
  14.  
  15. _BSS    segment word public 'BSS'
  16. _BSS    ends
  17.  
  18. _TEXT    segment byte public 'CODE'
  19.     assume    cs:_TEXT, ds:DGROUP
  20.  
  21. ;- I16INTR -------------------------------------------------------------;
  22. ;
  23. ; This is the interrupt 16H intercept where the hook processing is done.
  24. ;
  25. ; Entry parms:    AH is the function selector
  26. ;        Functions 0 and 1 are implemented.
  27. ; Exit parms:    AX is the return data for function 0
  28. ;        For function 1, flags == NZ indicates data available
  29. ;-----------------------------------------------------------------------;
  30. i16intr proc far
  31.     cmp    ah,0            ; Test the entry value of AH
  32.     je    i16f0            ; to decode the function.
  33.     cmp    ah,1            ; If management is needed for 
  34.     jne    $+5            ; function #2, another test must
  35.     jmp    i16f1            ; be added here.
  36.     jmp    dword ptr cs:[orig16]    ; Pass on to the original INT 16H.
  37. i16f0:                    ; Save BX and CX since
  38.     push    bx            ; they will be crashed by 
  39.     push    cx            ; the STK2LOC procedure.
  40.     call    stk2loc            ; Switch to a local stack.
  41.     push    bx            ; Save the stack switch flag.
  42.     push    si            ; Save the original SP and SS.
  43.     push    di
  44.     push    dx            ; Save the other misc registers.
  45.     push    es
  46.     push    ds
  47.     push    bp
  48.     sub    sp,2            ; Create local stack storage for
  49.     mov    bp,sp            ; a word - addressable by [bp].
  50. i16f0a:
  51.     mov    ds,cs:[ds_seg]        ; Setup DS addressability and
  52.     push    ss            ; place the parameter on the stack
  53.     push    bp            ; as the poll0 hook will expect.
  54.     call    ds:[_poll0_hook]    ; Call the poll0 hook procedure.
  55.     add    sp,4            ; Clean up the stack.
  56.     or    ax,ax            ; If the hook procedure is
  57.     jnz    i16f0b            ; asserting data, jmp to i16f0b.
  58.     mov    ah,1            ; Otherwise, enter a loop where
  59.     pushf                ; the actual keyboard and the
  60.     call    cs:[orig16]        ; polling hook are repeatedly tested.
  61.     jz    i16f0a            ; When data is detected from the
  62.     mov    ah,0            ; actual keyboard, use INT 16H
  63.     pushf                ; function 0 to retrieve it.
  64.     call    cs:[orig16]
  65.     mov    [bp],ax            ; Place the keycode in the stack var.
  66. i16f0b:    
  67.     mov    ds,cs:[ds_seg]        ; Setup DS addressability and 
  68.     push    ss            ; Place the parameter on the stack
  69.     push    bp            ; as the filter0 hook will expect.
  70.     call    ds:[_filter0_hook]    ; Call the filter0 hook procedure.
  71.     add    sp,4            ; Clean up the stack.
  72.     or    ax,ax            ; AX != 0 means that the hook proc
  73.     jnz    i16f0a            ; absorbed the key so get another.
  74.     mov    ax,[bp]            ; Else, put the keycode in AX and
  75.     add    sp,2            ; prepare to return to the caller.
  76.     pop    bp
  77.     pop    ds            ; Restore registers from the stack.
  78.     pop    es
  79.     pop    dx
  80.     pop    di
  81.     pop    si
  82.     pop    bx
  83.     call    stk2orig        ; Change back to the original stack.
  84.     pop    cx
  85.     pop    bx
  86.     iret
  87. i16f1:                    ; Process a function 1 call.
  88.     push    ax            ; Save AX, BX and CX since
  89.     push    bx            ; they will be crashed by 
  90.     push    cx            ; the STK2LOC procedure.
  91.     call    stk2loc            ; Switch to a local stack.
  92.     push    bx            ; Save the stack switch flag.
  93.     push    si            ; Save the original SP and SS.
  94.     push    di
  95.     push    dx            ; Save the other misc registers.
  96.     push    es
  97.     push    ds
  98.     push    bp
  99.     mov    ds,cs:[ds_seg]        ; Setup DS addressability and 
  100.     call    ds:[_poll1_hook]    ; call the poll1 hook procedure.
  101.     pop    bp
  102.     pop    ds
  103.     pop    es
  104.     pop    dx            ; Restore the registers.
  105.     pop    di            ; NOTE: the AX register must
  106.     pop    si            ; not be changed through this
  107.     pop    bx            ; section.
  108.     call    stk2orig        ; Switch to the original stack.
  109.     pop    cx
  110.     pop    bx
  111.     or    ax,ax            ; If AX != 0 then data is available.
  112.     pop    ax
  113.     jz    i16f1a
  114.     push    bp            ; Manipulate the zero flag in the
  115.     mov    bp,sp            ; flags image on the stack.
  116.     and    word ptr [bp+6],not 40h
  117.     pop    bp
  118.     iret                ; Return to the caller.
  119. i16f1a:    
  120.     jmp    cs:[orig16]        ; Pass on to the original BIOS when
  121. i16intr endp                ; no data available from a hook.
  122.  
  123. ;- STK2LOC -------------------------------------------------------------;
  124. ;
  125. ; This procedure manages the switch from the stack in effect when an
  126. ; interrupt 16H call is intercepted by i16intr. In many cases, the
  127. ; stack in effect will be that of the host OS.
  128. ;
  129. ; entry parms:    None
  130. ; exit parms:    BX flags whether or not a stack switch was done
  131. ;        DI and SI hold the original SS and SP (when a switch)
  132. ;        AX and CX are crashed
  133. ;-----------------------------------------------------------------------;
  134. stk2loc    proc    near
  135.     pop    cx            ; Get return address off of stack.
  136.     mov    ax,cs            ; If CS == SS then this is a 
  137.     mov    bx,ss            ; recursive entry so don't swtich
  138.     cmp    ax,bx            ; stacks.
  139.     mov    bx,0            ; BX is the stack switch flag for
  140.     je    s2la            ; stk2orig. if BX == 1, a switch
  141.     inc    bx            ; was done.
  142.     push    si            ; Using DI and SI to save the
  143.     push    di            ; original stack segment/pointer
  144.     mov    si,sp            ; between this procedure and the
  145.     mov    di,ss            ; stk2orig procedure.
  146.     cli                ; Must insure that no interrupts
  147.     mov    ss,ax            ; occur until the new stack is fully
  148.     mov    sp,offset loc_stack    ; defined.
  149.     sti
  150. s2la:
  151.     jmp    cx            ; Return to the caller.
  152. stk2loc    endp
  153.  
  154. ;- STK2ORIG ------------------------------------------------------------;
  155. ;
  156. ; Restore the original stack that was in effect when the interrupt 16H
  157. ; call was originally made.
  158. ;
  159. ; Entry parms:    BX is stack switch flag (from stk2loc)
  160. ;        DI and SI hold the original SS and SP values
  161. ; Exit parms:    CX is crashed
  162. ;-----------------------------------------------------------------------;
  163. stk2orig proc    near
  164.     pop    cx            ; Get return address off of stack.
  165.     or    bx,bx            ; If BX != 0 then a stack switch
  166.     jz    s2oa            ; was done by stk2loc and must
  167.     cli                ; be un-done here.
  168.     mov    ss,di            ; DI and SI hold the original
  169.     mov    sp,si            ; SS and SP values.
  170.     sti
  171.     pop    di            ; Restore these from the original
  172.     pop    si            ; stack.
  173. s2oa:
  174.     jmp    cx            ; Return to the caller
  175. stk2orig endp
  176.  
  177. ;- I22INTR -------------------------------------------------------------;
  178. ;
  179. ; An intercept of the INT 22H terminate vector saved in the PSP is 
  180. ; used to insure that no matter how the application may terminate, 
  181. ; the INT 16H interrupt vector is reset.
  182. ;
  183. ; Entry parms:    None
  184. ; Exit parms:    None - all registers must be preserved.
  185. ;-----------------------------------------------------------------------;
  186. i22intr    proc    far
  187.     push    ax
  188.     push    es
  189.     xor    ax,ax            ; Set ES to 0 to address vectors.
  190.     mov    es,ax
  191.     cli                ; No interrupts during vector change.
  192.     mov    ax,word ptr cs:[orig16]    ; Restore the original INT 16H
  193.     mov    es:[16h*4],ax        ; vector.
  194.     mov    ax,word ptr cs:[orig16+2]
  195.     mov    es:[16h*4+2],ax
  196.     sti
  197.     pop    es
  198.     pop    ax            ; Continue with the original
  199.     jmp    dword ptr cs:[orig22]    ; termination process.
  200. i22intr    endp
  201.  
  202. ;- I16SETUP ------------------------------------------------------------;
  203. ;
  204. ; This procedure should be called one time at the start of the 
  205. ; application to initialize the INT 16H and INT 22H intercept logic.
  206. ;
  207. ; Entry parms:    None
  208. ; Exit parms:    None
  209. ;-----------------------------------------------------------------------;
  210.     public    _i16setup
  211. _i16setup proc near
  212.     mov    cs:[ds_seg],ds        ; Save the caller's DS value for
  213.     mov    ax,3516h        ; later uses when calling hooks.
  214.     int    21h            ; Read the current INT 16H vector
  215.     mov    word ptr cs:[orig16],bx    ; and store in orig16.
  216.     mov    word ptr cs:[orig16+2],es
  217.     push    ds
  218.     push    cs
  219.     pop    ds            ; Make the INT 16H vector point
  220.     mov    dx,offset i16intr    ; to the intercept routine.
  221.     mov    ax,2516h
  222.     int    21h
  223.     pop    ds
  224.     mov    ah,51h            ; The original terminate vector
  225.     int    21h            ; is stored within the PSP. 
  226.     mov    es,bx            ; INT 21H, function 51H will return
  227.     cli                ; the current PSP segment in BX
  228.     mov    ax,es:[0ah]        ; Use this to modify the vector.
  229.     mov    word ptr cs:[orig22],ax
  230.     mov    ax,es:[0ch]
  231.     mov    word ptr cs:[orig22+2],ax
  232.     mov    word ptr es:[0ah],offset i22intr
  233.     mov    es:[0ch],cs
  234.     ret                ; Done with the initialization.
  235. _i16setup endp
  236.  
  237. ds_seg    dw    ?        ; the DS value expected by hook procedures
  238. orig16    dd    ?        ; original contents of the INT 16H vector
  239. orig22    dd    ?;         ; original contents of the INT 22H vector
  240.  
  241. ; A local stack is maintained for use by the INT 16H intercept logic.
  242. ; This stack is in effect when hook procedures are called. It may
  243. ; need to be enlarged if significant procedure nesting or recursion
  244. ; will occur.
  245.  
  246.     dw    512 dup(?)
  247. loc_stack label byte
  248.  
  249. _TEXT    ends
  250.     end
  251.