home *** CD-ROM | disk | FTP | other *** search
/ Sound Sensations! / sound_sensations.iso / midifile / cmtcmu / break.asm < prev    next >
Assembly Source File  |  1990-06-28  |  9KB  |  369 lines

  1.     title BREAK - handle ctrl-break 
  2. ;***************************************************************************** 
  3. ;        Change Log 
  4. ;  Date        | Change 
  5. ;-----------+----------------------------------------------------------------- 
  6. ; 11-Aug-85 | Created 
  7. ;  1-Sep-85 | Rearranged so _clrctl precedes its call (needed in P model) 
  8. ; 31-Dec-85 | Made special copy for Adagio support.  Stripped out most stuff 
  9. ;        | and handle DOS ctrl-break exit 
  10. ;  1-Jan-86 | Use 1 for control-break and 2 for control-C 
  11. ;  1-Jan-86 | Cause return to skip over sub instruction (forcing ignore code 
  12. ;        | acceptance) on PC/AT 
  13. ;  2-Jan-86 | take out m: from include m:dos.mac 
  14. ;****************************************************************************/ 
  15.     include dos.mac 
  16. debug=0 
  17.     subttl Documentation 
  18. ;***************************************************************************** 
  19. ; This code uses the standard Lattice interface.  The logical device 'm:' 
  20. ; represents the memory model being used.  Supply your own path to dos.mac 
  21. ; This code is intended to allow me to break out of various perverse 
  22. ; loops in my application code.      
  23. ;              * * * W A R N I N G * * * 
  24. ; This code is an extreme *HACK*.  It solves my problem.  It may not solve 
  25. ; yours.  I make no guarantees.     Use at your own risk! 
  26. ;                 Restrictions 
  27. ; Failure to clear the handler before exiting the program will lead to 
  28. ; various bizarre behavior.  Calling the initialization more than once 
  29. ; will confuse the world beyond practical recovery. 
  30. ;                   Abstract 
  31. ; A procedure is called to establish the existence of the control-break  
  32. ; handler (interrupt 1BH).  If a control-break is taken during program 
  33. ; the flag _CBREAK is set to true 
  34. ; This code is to be linked into the user's application. 
  35. ; This code also sets up a handler for the DOS ctrl-brk exit; this is called 
  36. ; if DOS sees a C-C character come by. 
  37. ;  
  38. ;               * * * B E W A R E * * * 
  39. ; This code is delicate and high-risk.    It works well enough for my one 
  40. ; application.    I may have missed all sorts of bizarre DOS or BIOS hacks. 
  41. ; It is not guaranteed to be bug-free.    The user assumes all risk in using 
  42. ; it.  This is code that should be used only if you understand enough of 
  43. ; DOS/BIOS hacking to be sure it will work for you. 
  44.   
  45.     subttl Interface specifications 
  46. ;----------------------------------------------------------------------------- 
  47. ; extern void _setctl(); 
  48. ;     
  49. ; Effects:  
  50. ;    Establishes a Ctrl-brk abort handler 
  51. ; Limitations: 
  52. ;    May only be called once; subsequent calls may damage universe 
  53. ;  
  54. ;----------------------------------------------------------------------------- 
  55. ; extern void _clrctl(); 
  56. ; Effects:  
  57. ;    Resets the Ctrl-brk abort handler 
  58. ; Limitations: 
  59. ;    Should be called only if _setctl() has been called.  However, if 
  60. ;    _setctl has not already been called, nothing will happen. 
  61. ;***************************************************************************** 
  62.   
  63.     subttl Working storage 
  64. extrn    _CBREAK:word 
  65. ; This storage is in the data segment 
  66. ;    public    _CBREAK 
  67.     DSEG 
  68.     even 
  69. ;_CBREAK    dw    0 
  70. OLD_BIOS label    DWORD        ; we store former 1BH vector here 
  71. OLD_BIP DW    0        ; 0, not ? 
  72. OLD_BCS DW    0        ; 0, not ? 
  73.  
  74. OLD_DOS label    DWORD        ; we store former 23H vector here 
  75. OLD_DIP DW    0 
  76. OLD_DCS dw    0         
  77.  
  78.     ENDDS 
  79.  
  80.   
  81.     subttl Vector locations 
  82. VECTORS SEGMENT AT 0H 
  83.     ORG    1BH*4        ; BIOS ctrl-brk interrupt vector 
  84. CTLBRK    LABEL    DWORD 
  85. CTLBRK_IP DW    ?        ; IP of BIOS control-break vector 
  86. CTLBRK_CS DW    ?        ; CS of BIOS control-break vector 
  87.  
  88.     ORG    23H*4        ; DOS ctrl-brk interrupt vector 
  89. DOSCBRK LABEL    DWORD 
  90. DOSC_IP     DW    ? 
  91. DOSC_CS     DW    ? 
  92. VECTORS ENDS 
  93.  
  94.  
  95.   
  96.     subttl    Code segment storage  
  97. ; This is in the code segment because I don't know how to make it addressible 
  98. ; in the data segment 
  99.     PSEG 
  100.  
  101.   
  102.     subttl    CTLSEEN - CTRL-BREAK handler 
  103. ;----------------------------------------------------------------------------- 
  104. ;                    ctlseen 
  105. ; Inputs: 
  106. ;    None; called as interrupt routine via interrupt 1BH 
  107. ; Result: 
  108. ;    AL=0FFH 
  109. ; Effects: 
  110. ;    sets _CBREAK to true.   
  111. ;----------------------------------------------------------------------------- 
  112.  
  113. CTLSEEN PROC FAR 
  114.  
  115.  
  116. if debug 
  117.     int  3 
  118. endif 
  119.     push    ax 
  120.     push    ds 
  121.     mov    ax,seg _CBREAK 
  122.     mov    ds,ax 
  123.     mov    ds:_CBREAK,1 
  124.     pop    ds 
  125.     pop    ax 
  126.     push    es 
  127.     mov    AX,0F000H    ; from the ROM,  
  128.     mov    ES,AX        ; we want pc ID 
  129.     mov    AH,ES:0FFFEH    ; The Peter Norton Programmer's Guide to the 
  130.                 ; IBM PC, page 60 
  131.     cmp    AH,0FCH        ;  PC/AT? 
  132.     jnz    no 
  133. if debug 
  134.     int    3        ; WARNING!  If you have this debug trap 
  135.                 ; enabled, and continue from it, the 
  136.                 ; ctrl-key-up transition is lost (because 
  137.                 ; the key went up to talk to the debugger) 
  138.                 ; this confuses the world; you will have to 
  139.                 ; hit the control-key once to get the 
  140.                 ; world resynchronized. 
  141.  
  142. endif 
  143. ; We increment the return address by 2 
  144. ;    +-------------------+ 
  145. ;  SS    |      (ES)        |  ES:0[BP] 
  146. ;    +-------------------+ 
  147. ;    |      (BP)        |  ES:2[BP] 
  148. ;    +-------------------+ 
  149. ;    |    IP        |  ES:4[BP] 
  150. ;    +-------------------+ 
  151. ;    |    CS        |  ES:6[BP] 
  152. ;    +-------------------+ 
  153.     mov    AX,SS     
  154.     mov    ES,AX 
  155.     push    BP 
  156.     mov    BP,SP 
  157.     inc    WORD PTR ES:4[BP] 
  158.     inc    WORD PTR ES:4[BP] 
  159.     pop    BP 
  160. no:    mov    AX,-1 
  161.             ; "ignore" character 
  162.             ; PC/XT ref page A-31 lines 2090-2091, page A-33 
  163.             ; lines 2217-2219 
  164.             ; PC/AT ref page 5-118 loc 2AE..285 indicates this 
  165.             ; has no effect for the /AT, which is why we did 
  166.             ; the above hack 
  167.     pop    ES 
  168.     iret                ;return  
  169.  
  170. CTLSEEN ENDP 
  171.  
  172. CTLC    PROC    FAR        ; Control-C handler 
  173.     push    ax 
  174.     push    ds 
  175.     mov    ax,seg _CBREAK 
  176.     mov    ds,ax 
  177.     mov    ds:_CBREAK,2 
  178.     pop    ds 
  179.     pop    ax 
  180.     iret                ;return  
  181. CTLC    ENDP 
  182.   
  183.     subttl    _clrctl - Clear CTL-BRK vector 
  184. ;----------------------------------------------------------------------------- 
  185. ; extern void _clrctl(); 
  186. ; Resets the ctrl-break interrupt vector 
  187. ;----------------------------------------------------------------------------- 
  188.     PUBLIC    _clrctl 
  189.     IF    LPROG 
  190. _clrctl PROC FAR 
  191.     ELSE 
  192. _clrctl PROC NEAR 
  193.     ENDIF 
  194.  
  195. ; OldES := ES; 
  196.  
  197.     push    ES        ; save old ES 
  198.     push    AX        ; save old AX 
  199.     push    BX 
  200.  
  201. if debug 
  202.     int 3 
  203.     mov    AH,62H 
  204.     int    21H        ; get program segment prefix 
  205.     mov    PSP,BX        ; save it 
  206. endif 
  207.  
  208. ; ES := Segment(&Vectors); 
  209.  
  210.     mov    AX,VECTORS 
  211.     mov    ES,AX         
  212.     ASSUME ES:VECTORS 
  213.  
  214. ; Disable_Interrupts(); 
  215.  
  216.     CLI            ; turn off interrupts 
  217.  
  218. ; if(OLD_BIOS == 0) goto NoVectorStored 
  219.  
  220.     mov    AX,WORD PTR OLD_BIOS 
  221.     cmp    AX,0        ; is it zero? 
  222.     je    NoBIOSStored 
  223.  
  224. ; CTLBRK.IP := OLD_BIOS.IP 
  225.  
  226.     mov    WORD PTR CTLBRK,AX 
  227.  
  228. ; CTLBRK.CS := OLD_BIOS.CS 
  229.  
  230.     mov    AX,WORD PTR OLD_BIOS[2] 
  231.     mov    WORD PTR CTLBRK[2],AX 
  232.  
  233. NoBIOSStored: 
  234.  
  235.     mov    AX,WORD PTR OLD_DOS 
  236.     cmp    AX,0        ; initialized? 
  237.     je    NoDOSStored    ; no, no dos vector 
  238.  
  239. ; DOSCBRK.IP = OLD_DOS.IP 
  240.  
  241.     mov    WORD PTR DOSCBRK,AX 
  242.  
  243. ; DOSCBRK.CS := OLD_DOS.CS 
  244.  
  245.     mov    AX,WORD PTR OLD_DOS[2] 
  246.     mov    WORD PTR DOSCBRK[2],AX 
  247.  
  248. NoDOSStored: 
  249.  
  250. ; Enable_interrupts(); 
  251.  
  252.     STI        ; allow interrupts 
  253.  
  254. ; ES := OldES; 
  255.  
  256.     pop    BX 
  257.     pop    AX 
  258.     pop    ES     
  259.  
  260.     ret        ; return to caller 
  261.  
  262. PSP:    DW    ? 
  263. _clrctl    ENDP 
  264.   
  265.     subttl    _setctl - Set CTL-BRK vector 
  266. ;----------------------------------------------------------------------------- 
  267. ; extern void _setctl() 
  268. ;----------------------------------------------------------------------------- 
  269.  
  270.     PUBLIC    _setctl 
  271.     IF LPROG 
  272. _setctl    PROC    FAR 
  273.     ELSE 
  274. _setctl    PROC NEAR            ; set CTL-BRK interrupt 
  275.     ENDIF 
  276.     push    BP            ; C prolog 
  277.     mov    BP,SP            ; ... 
  278.  
  279. if debug 
  280.     int    3 
  281. endif 
  282.  
  283.     ASSUME ES:VECTORS 
  284.  
  285. ; OldES := ES; 
  286.  
  287.     push    ES        ; save old ES 
  288.     push    AX        ; save old AX 
  289.  
  290. ; ES := Segment(&Vectors); 
  291.  
  292.     mov    AX,VECTORS 
  293.     mov    ES,AX         
  294.  
  295. ; Disable_Interrupts(); 
  296.  
  297.     CLI            ; turn off interrupts 
  298.  
  299. ; OLD_BIOS.IP := CTLBRK.IP 
  300.  
  301.     mov    AX,WORD PTR CTLBRK 
  302.     mov    WORD PTR OLD_BIOS,AX 
  303.  
  304. ; OLD_BIOS.CS := CTLBRK.CS 
  305.  
  306.     mov    AX,WORD PTR CTLBRK[2] 
  307.     mov    WORD PTR OLD_BIOS[2],AX 
  308.  
  309. ; CTLBRK := &CTLSEEN 
  310.  
  311.     mov    CTLBRK_IP,OFFSET CTLSEEN 
  312.     mov    CTLBRK_CS,CS 
  313.  
  314. ; OLD_DOS.IP := DOSCBRK.IP 
  315.  
  316.     mov    AX,WORD PTR DOSCBRK 
  317.     mov    WORD PTR OLD_DOS,AX 
  318.  
  319. ; OLD_DOS.CS := DOSCBRK.CS 
  320.  
  321.     mov    AX,WORD PTR DOSCBRK[2] 
  322.     mov    WORD PTR OLD_DOS[2],AX 
  323.  
  324. ; DOSCBRK := &CTLC 
  325.  
  326.     mov    DOSC_IP,OFFSET CTLC 
  327.     mov    DOSC_CS,CS 
  328.  
  329. ; Enable_interrupts(); 
  330.  
  331.     STI        ; allow interrupts 
  332.  
  333. ; ES := OldES; 
  334.  
  335.     pop    AX 
  336.     pop    ES     
  337.  
  338. ; return; 
  339.     pop    BP    ; C epilog 
  340.     ret        ; return to caller 
  341.  
  342. _setctl    ENDP 
  343.  
  344.     ENDPS 
  345.     END 
  346.