home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / t / tel2305s.zip / ENGINE / NCSABRK.ASM < prev    next >
Assembly Source File  |  1991-10-20  |  11KB  |  445 lines

  1. ;
  2. ;  ncsabrk.asm
  3. ;  Support for BREAK interupts in NCSA Telnet
  4. ;****************************************************************************
  5. ;*                                                                            *
  6. ;*                                                                            *
  7. ;*      part of NCSA Telnet                                                    *
  8. ;*      by Tim Krauskopf, VT100 by Gaige Paulsen, Tek by Aaron Contorer        *
  9. ;*          Kurt Mahan, Heeren Pathak, and Quincey Koziol                        *
  10. ;*                                                                            *
  11. ;*      National Center for Supercomputing Applications                        *
  12. ;*      152 Computing Applications Building                                    *
  13. ;*      605 E. Springfield Ave.                                                *
  14. ;*      Champaign, IL  61820                                                    *
  15. ;*                                                                            *
  16. ;*                                                                            *
  17. ;****************************************************************************
  18.  
  19.     TITLE    NCSABRK    -- LOW-LEVEL I/O FOR SANE HARDWARE HANDLING
  20. ;Microsoft EQU 1
  21. ;Lattice EQU 1
  22. ifndef Microsoft
  23.     ifndef Lattice
  24.         if2
  25.             %out
  26.             %out ERROR: You have to specify "/DMicrosoft" OR "/DLattice" on the
  27.             %out        MASM command line to determine the type of assembly.
  28.             %out
  29.         endif
  30.         end
  31.     endif
  32. endif
  33.  
  34. ;
  35. ;   From original code by Tim Krauskopf    1984-1985
  36. ;
  37. ;    Support for the BREAK interupt added, June 1990, Quincey Koziol
  38. ;
  39. ;   National Center for Supercomputing Applications
  40. ;
  41.     NAME    NBREAK
  42.  
  43. ;
  44. ;  Internal data 
  45. ;
  46. X     EQU    6                    ;  for the large model programs
  47. ;  Match the model directive with the application model
  48. .model large
  49.  
  50. ;-------------------------------------------------------------------------------------------
  51. ;    MACROs and EQUATES
  52. ;-------------------------------------------------------------------------------------------
  53.  
  54. sim_int macro    num
  55.     pushf
  56.     call    cs:orig_&num
  57. endm
  58.  
  59. TRUE    equ    1
  60. FALSE    equ    0
  61.  
  62. ;  large model flag parameter equates
  63. if @CODESIZE
  64.     FLG_OFF    equ    [bp+6]
  65.     FLG_SEG    equ    [bp+8]
  66.  
  67. ;  small model flag parameter equates
  68. else
  69.     FLG_OFF    equ    [bp+4]
  70.     FLG_SEG    equ    [bp+6]
  71. endif
  72.  
  73. ;
  74. ;   The subroutines to call from C
  75. ;
  76. ifdef Microsoft
  77. ;_TEXT    segment    public    'CODE'
  78. ;    assume CS:_TEXT
  79. .code
  80.     PUBLIC    _install_break,_remove_break
  81. else
  82.     PSEG
  83.     PUBLIC    install_break,remove_break
  84. endif
  85.  
  86. ;-------------------------------------------------------------------------------------------
  87. ;    The replaced addrss and the flag pointer are in the code
  88. ;    segment so they will be accessable to the interrupt 
  89. ;    replacement code.
  90. ;-------------------------------------------------------------------------------------------
  91.  
  92. ;  far address of application program's Ctrl-C/Break
  93. ;  detected flag
  94. flag        dd    0
  95.  
  96. orig_16h    dd    0        ;  far addresses of
  97. orig_1bh    dd    0        ;  the original
  98. orig_23h    dd    0        ;  vectors
  99.  
  100. ;  flag to let capture () & release () know there are 
  101. ;  valid addresses in org_??h
  102. replaced    db    FALSE
  103.  
  104.  
  105. assume    ds:@curseg
  106.  
  107. ;**************************************************************************
  108. ;
  109. ;  Routines to install and deinstall a BREAK routine which intersepts ctrl-c's
  110. ;
  111. ;
  112. BREAKINT        EQU    4*23H        ; User hook to break int
  113.  
  114. ;----------------------------------------------------------------------------------------------
  115. ;    The following "installation" prodecure is a near call even 
  116. ;    in the large model enironment
  117. ;----------------------------------------------------------------------------------------------
  118. install_vectors    proc    near
  119.  
  120. ;  get current int 16h vector
  121.     mov    ax, 3516h
  122.     int    21h
  123.     mov    word ptr orig_16h, bx
  124.  
  125. ;  save the vector we found
  126.     mov    word ptr orig_16h+2, es
  127.  
  128. ;  get address of new handler
  129.     lea    dx, sixteen_handler
  130.  
  131. ;  set the vector to point
  132. ;  to our routine
  133.     mov    ax, 2516h
  134.     int    21h
  135.  
  136. ;---------------------------------------------------------------------------------------------
  137. ;    Replacement of 1bh is mandatory if you want to prevent int
  138. ;    1bh (Ctrl-Break) from setting the flag DOS looks at
  139. ;----------------------------------------------------------------------------------------------
  140.  
  141. ;  get current int 1bh vector
  142.     mov    ax, 351bh
  143.     int    21h
  144.     mov    word ptr orig_1bh, bx
  145.  
  146. ;  save the vetor we found
  147.     mov    word ptr orig_1bh+2, es
  148.  
  149. ;  get address of new handler
  150.     lea    dx, int1b_handler
  151.  
  152. ;  set the vector to point
  153. ;  to our routine
  154.     mov    ax, 251bh
  155.     int    21h
  156.  
  157. ;---------------------------------------------------------------------------------------------
  158. ;    Replacement of 23h is *not* necessary to trap Ctrl C or
  159. ;    Ctrl-Break, however, if you want to break from your code
  160. ;    using Ctrl-2 or Alt-3, int 23h is where we'll make a call to
  161. ;    release () so the installed interrupt handlers will be un-
  162. ;    installed, thus preventing a system hang on return to DOS
  163. ;----------------------------------------------------------------------------------------------
  164.  
  165. ;  get current int 23h vector
  166.     mov    ax, 3523h
  167.     int    21h
  168.     mov    word ptr orig_23h, bx
  169.  
  170. ;  save the vector we found
  171.     mov    word ptr orig_23h+2, es
  172.  
  173. ;  get address of new handlers
  174.     lea    dx, int23_handler
  175.  
  176. ;  set the vector to  point
  177. ;  to our routine
  178.     mov     ax, 2523h
  179.     int    21h
  180.     ret
  181. install_vectors endp
  182.  
  183. ;****************************************************************
  184. ; install_break
  185. ;
  186. ;  install the break interrupt handler, the handler is technically
  187. ;  part of this procedure.
  188. ;
  189. ifdef Microsoft
  190. _install_break    proc     far
  191. else
  192. install_break    proc    far
  193. endif
  194. ;  establish the stack frame
  195.     push    bp
  196.     mov    bp, sp
  197.  
  198. ;  save the application programs ds & es registers
  199.     push    ds
  200.     push    es
  201.  
  202. ;  make ds point to the code segment for vector swaps
  203.     push    cs
  204.     pop    ds
  205.  
  206. ;  check if already installed
  207.     cmp    replaced, TRUE
  208.     jz    capture_exit
  209.  
  210. ;  get the offset and segment of application "break_flag"
  211.     mov    ax, word ptr FLG_OFF
  212.     mov    word ptr flag, ax
  213.     mov    ax, word ptr FLG_SEG
  214.     mov    word ptr flag+2, ax
  215.  
  216. ;  install the replacements
  217. ;  NOTE:  near overides for when large model
  218.     call    near ptr install_vectors
  219.  
  220. ;  flag that things have changed
  221.     mov    byte ptr replaced, TRUE
  222.  
  223. ;  restore registers and stack frame
  224. capture_exit:
  225.     pop    es
  226.     pop    ds
  227.     pop    bp
  228.     ret
  229. ifdef Microsoft
  230. _install_break    endp
  231. else
  232. install_break    endp
  233. endif
  234.  
  235. assume cs:@curseg, ds:nothing, es:nothing
  236.  
  237. ;****************************************************************
  238. ; remove_break
  239. ;
  240. ;  restores interrupt 16h, 1bh, 23h to what they were before installing our
  241. ;    break handler
  242. ;
  243. ifdef Microsoft
  244. _remove_break    proc     far
  245. else
  246. remove_break    proc    far
  247. endif
  248. ;  save regs used locally
  249.     push    ds
  250.     push    dx
  251.  
  252. ;  save the flags in case this routine has been called 
  253. ;  by the int 23h handler
  254.     pushf
  255.  
  256. ;  check that _capture() has installed the handlers
  257.     cmp    cs:replaced, TRUE
  258.     jnz    release_exit
  259.  
  260. ;  ds:dx gets the address of the saved original
  261. ;  interrupt 16h vector
  262.     lds    dx, cs:orig_16h
  263.  
  264. ;  reset the int 16h vector
  265.     mov    ax, 2516h
  266.     int    21h
  267.  
  268. ;  ds:dx gets the address of the saved original
  269. ;  interrupt 1bh vector
  270.     lds    dx, cs:orig_1bh
  271.     
  272. ;  reset the int 1bh vector
  273.     mov    ax, 251bh
  274.     int    21h
  275.  
  276. ;  ds:dx gets the address of the saved original
  277. ;  interrupt 23h vector
  278.     lds    dx, cs:orig_23h
  279.  
  280. ;  reset the int 23h vector
  281.     mov    ax, 2523h
  282.     int    21h
  283.  
  284. ;  indicate that vectors are no longer replaced
  285.     mov    cs:replaced, FALSE
  286.  
  287. release_exit:
  288. ;  restore flags, dx & ds
  289.     popf
  290.     pop    dx
  291.     pop    ds
  292.     ret
  293. ifdef Microsoft
  294. _remove_break    endp
  295. else
  296. remove_break    endp
  297. endif
  298.  
  299. assume cs:@curseg, ds:nothing, es:nothing
  300.  
  301. ;  place to store the int 16h function parameter
  302. ;  re-entrance is not a problem
  303. save_funct    db    ?
  304.  
  305. ;------------------------------------------------------------------------------------------------
  306. ;    Sixteen_handler is a far proc regardless of the memory model
  307. ;    specified in the ".model" directive since it is an interrupt 
  308. ;    replacement routine.
  309. ;------------------------------------------------------------------------------------------------
  310.  
  311. sixteen_handler proc far
  312.  
  313. ;  save the function value
  314.     mov    cs:save_funct, ah
  315.  
  316. ;  convert to the non-extended numbers
  317.     and    ah, 11101111b
  318.  
  319. ; is it a shift status request
  320.     cmp    ah, 2
  321.  
  322. ;  lower than shift status request, we'll take care of it
  323.     jb    not_shift_status_req
  324.  
  325. ;  put back the callers function, pass it to the BIOS &
  326. ;  don't come back here
  327.     mov    ah, cs:save_funct
  328.     jmp    cs:orig_16h
  329.  
  330. not_shift_status_req:
  331. ;  if it is a "is_keyready" call, handle it in the 
  332. ;  keyready_call block of code
  333.     cmp    ah, 1
  334.     jz    keyready_call
  335.  
  336. ;  must be a "get_key" request
  337. get_key_call:
  338.  
  339. ;  restore the callers original function value
  340.     mov    ah, cs:save_funct
  341.  
  342. ; simulate an interrupt
  343.     sim_int    16h
  344.  
  345. ;  did the BIOS return the Ctrl-C keycode
  346.     cmp    ax, 2e03h
  347.  
  348. ;  no, so we can return to caller
  349.     jnz    iret_back
  350.  
  351. ;  the BIOS returned a Ctrl-C keycode, so
  352. ;  set the flag in the application program
  353.     call    near ptr set_flag
  354.  
  355. ;  the Ctrl-C dey is thrown away so go bakc and get
  356. ;  another key
  357.     jmp    get_key_call
  358.  
  359. keyready_call:
  360. ;  restore the callers original function value
  361.     mov    ah, cs:save_funct
  362.  
  363. ; simulate an interrupt
  364.     sim_int    16h
  365.  
  366. ;  if the zero flag is set (by the BIOS), the keyboard
  367. ;  buffer is empty - ok to return to caller
  368.     jz    ok_to_go_back
  369.  
  370. ;  compare the key at the heaad of the keyboard buffer
  371. ;  with Ctrl-C keycode.  This compare will leave the Z flag
  372. ; indicating a key is available.
  373.     cmp    ax, 2e03h
  374.     jnz    ok_to_go_back
  375.  
  376. ;  key was Ctrl-C, set the application program flag
  377.     call    near ptr set_flag
  378.  
  379. ;  remove Ctrl-C keycode from the keyboard buffer
  380.     mov    ah, 0
  381.     sim_int    16h
  382.  
  383. ;  log back to see if a non Ctrl-C key is ready
  384.     jmp    keyready_call
  385.  
  386. ok_to_go_back:
  387. ;  throw away flags of our caller and return
  388.     ret    2
  389.  
  390. iret_back:
  391. ;  restore callers flags on return
  392.     iret
  393. sixteen_handler endp
  394.  
  395.  
  396. ;------------------------------------------------------------------------------------------
  397. ;    int1b_handler is a far proc regardless of memory model
  398. ;    set the application program flag and return
  399. ;------------------------------------------------------------------------------------------
  400. int1b_handler proc far
  401.     call    near ptr set_flag
  402.     iret
  403. int1b_handler endp
  404.  
  405. ;------------------------------------------------------------------------------------------
  406. ;    int23_handler is a far proc regardless of memory model
  407. ;    used here to allow Ctrl-2 or Alt-3 to "break" the program
  408. ;    execution.
  409. ;
  410. ;    restore the original vectors and execute the original Ctrl-C
  411. ;    interrupt handler
  412. ;------------------------------------------------------------------------------------------
  413. int23_handler proc far
  414. ;    call _release
  415.     jmp    cs:orig_23h
  416. int23_handler endp
  417.  
  418. ;------------------------------------------------------------------------------------------
  419. ;    set_flag is a near procedure regardless of memory model
  420. ;
  421. ;    Use the address passed to _capture() and set the integer
  422. ;    refrenced to one.
  423. ;------------------------------------------------------------------------------------------
  424.  
  425. set_flag proc near
  426.     push ds
  427.     push si
  428.  
  429. ;  get the address of the application break flag
  430.     lds    si,cs:flag
  431.  
  432. ;  set the flag to one
  433.     mov    word ptr [si], 1
  434.     pop    si
  435.     pop    ds
  436.     ret
  437. set_flag endp
  438.  
  439. ifdef Microsoft
  440. ;_TEXT    ENDS
  441. else
  442.     endps
  443. endif
  444.     end
  445.