home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l440 / 2.ddi / CHAP5 / TSRUTIL.ASM < prev   
Encoding:
Assembly Source File  |  1990-09-26  |  6.2 KB  |  251 lines

  1. ;TSRUTIL.ASM
  2.  
  3. ;Define segment names used by C
  4. ;
  5. _TEXT   segment byte public 'CODE'
  6. _TEXT   ends
  7.  
  8. CONST   segment word public 'CONST'
  9. CONST   ends
  10.  
  11. _BSS    segment word public 'BSS'
  12. _BSS    ends
  13.  
  14. _DATA   segment word public 'DATA'
  15. _DATA   ends
  16.  
  17. DGROUP  GROUP   CONST, _BSS, _DATA
  18.  
  19.     assume  CS:_TEXT, DS:DGROUP  
  20.  
  21.     public  _new_int13, _init_intr
  22. IFDEF MULTI
  23.     public  _timer_int_chain
  24.     public  _new_int10, _new_int25, _new_int26
  25. ELSE
  26.     public  _deinstall
  27. ENDIF
  28.  
  29.     extrn   _ss_save:near       ;save foreground SS
  30.     extrn   _sp_save:near       ;save foreground SP
  31.     extrn   _unsafe_flag:near   ;if true, don't interrupt
  32.     extrn   _old_int13:near     
  33. IFDEF MULTI
  34.     extrn   _old_int8:near      
  35.     extrn   _old_int10:near     
  36.     extrn   _old_int25:near     ; note difference between
  37.     extrn   _old_int26:near     ; old_int25 and _old_int25!
  38. ELSE
  39.     extrn   _multiplex_id:near  ;our int 2f id byte
  40. ENDIF
  41.  
  42. _TEXT   segment
  43.  
  44. IFNDEF MULTI
  45. ;*****
  46. ;void far deinstall(void)
  47. ;function to use int 2f to ask TSR to deinstall itself
  48. ;the registers are probably all changed when our tsr exits
  49. ;so we save then and perform the INT 2f. The TSR exit will
  50. ;eventually bring us back here. Then the registers are restored
  51. ;This function is called from the foreground, not the TSR 
  52.  
  53. DEINSTALL   equ     1
  54.  
  55. _deinstall       proc    far
  56.     push si
  57.     push di
  58.     push bp
  59.     mov word ptr _ss_save,ss         ;save our stack frame
  60.     mov word ptr _sp_save,sp
  61.  
  62.     mov cs:_ds_save,ds      ; save DS for later restore
  63.  
  64.     mov bx,cs
  65.     mov dx,offset TerminateAddr ;bx:dx points to terminate address
  66.     mov ah, byte ptr _multiplex_id
  67.     mov al, DEINSTALL
  68.     int 2fh                 ;call our TSR
  69. ;
  70. ;if TSR terminates ok, we'll skip this code and return to Terminate Addr
  71. ;
  72.     jmp short NoTerminate
  73.  
  74. TerminateAddr:
  75. ;Restore DS and stack
  76.         mov     ax,cs:_ds_save  ;bring back our data segment
  77.         mov     ds,ax           ;destroyed by int 2f
  78.  
  79.         mov al,2            ;Set value for success
  80.  
  81.         mov     ss, word ptr _ss_save   ;restore our stack        
  82.         mov     sp, word ptr _sp_save   ;destroyed by int 2f
  83.  
  84. NoTerminate:
  85.         cbw             ;Extend return value to word
  86.         pop bp
  87.         pop di
  88.         pop si
  89.         ret
  90. _deinstall endp
  91. ENDIF
  92.  
  93. ;*****
  94. ;void inc_unsafe_flag(void) - increment unsafe flag
  95. ;*****
  96. inc_unsafe_flag proc    far
  97.     push    ax
  98.     push    ds
  99.     mov ax,DGROUP       ;make DS = to our TSR C data segment
  100.     mov ds,ax
  101.  
  102.     inc word ptr _unsafe_flag
  103.  
  104.     pop ds              ;put DS back to whatever it was
  105.     pop ax
  106.     ret
  107. inc_unsafe_flag endp
  108.  
  109. ;*****
  110. ;void dec_unsafe_flag(void) - decrement unsafe flag
  111. ;*****
  112. dec_unsafe_flag proc    far
  113.     push    ax
  114.     push    ds
  115.     mov ax,DGROUP       ;make DS = to our TSR 'C' data segment
  116.     mov ds,ax
  117.  
  118.     dec word ptr _unsafe_flag 
  119.  
  120.     pop ds              ;put DS back to whatever it was
  121.     pop ax
  122.     ret
  123. dec_unsafe_flag endp
  124.  
  125. ;we can't trap the following interrupts in C for a number of
  126. ;reasons
  127. ;   INT 13 returns info in the FLAGS, but a normal IRET
  128. ;   restores the flags
  129. ;
  130. ;   INT 25 & 26 leave the flags on the stack.  The user
  131. ;   must pop the off after performing an INT 25 or 26
  132. ;
  133. ;   These interrupts pass information via registers such
  134. ;   as DS. We don't want to change DS.
  135. ;
  136. ;   Since DS is unknown, we must call the old interrupts
  137. ;   via variables in the code segment. The _init_intr routine
  138. ;   sets up these CS variables from ones with nearly-identical
  139. ;   names in the C data segment in TSREXAMP.C.
  140.  
  141. ;*****
  142. ;void far init_intr(void)
  143. ;move interrupt pointer saved in the C program to our CS data area
  144. ;*****
  145. _init_intr proc far
  146.         push    es
  147.         push    bx
  148.  
  149. IFDEF MULTI
  150.         les     bx,dword ptr _old_int10
  151.         mov     word ptr cs:old_int10,bx
  152.         mov     word ptr cs:old_int10+2,es
  153.  
  154.         les     bx,dword ptr _old_int25
  155.         mov     word ptr cs:old_int25,bx
  156.         mov     word ptr cs:old_int25+2,es
  157.  
  158.         les     bx,dword ptr _old_int26
  159.         mov     word ptr cs:old_int26,bx
  160.         mov     word ptr cs:old_int26+2,es
  161. ENDIF
  162.         ; note incredibly confusing distinction 
  163.         ; between e.g. _old_int13 and old_int13
  164.         les     bx,dword ptr _old_int13
  165.         mov     word ptr cs:old_int13,bx
  166.         mov     word ptr cs:old_int13+2,es
  167.  
  168.         pop     bx
  169.         pop     es
  170.         ret
  171. _init_intr endp
  172.  
  173. ;*****
  174. ;void far new_int13(void) - disk interrupt
  175. ;*****
  176. _new_int13 proc far             
  177.     call    inc_unsafe_flag
  178.     pushf   ;simulate interrupt call    
  179.     call    cs:old_int13
  180.     call    dec_unsafe_flag        
  181.     ret 2   ; leave flags intact
  182. _new_int13 endp
  183.  
  184. IFDEF MULTI
  185. ;*****
  186. ;void far new_int10(void) - video interrupt
  187. ;*****
  188. _new_int10 proc far             
  189.     call    inc_unsafe_flag
  190.     pushf   ;simulate interrupt call    
  191.     call    cs:old_int10
  192.     call    dec_unsafe_flag        
  193.     iret
  194. _new_int10 endp
  195.  
  196. ;*****
  197. ;void far new_int25(void) - MS-DOS absolute sector read
  198. ;*****
  199. _new_int25  proc far                
  200.     call    inc_unsafe_flag
  201.     call    cs:old_int25
  202.     call    dec_unsafe_flag 
  203.     ret ; user must pop flags - MS-DOS convention
  204.         ; so leave them on the stack
  205. _new_int25 endp
  206.  
  207. ;*****
  208. ;void far new_int26(void) - MS-DOS absolute sector write
  209. ;*****
  210. _new_int26 proc far                 
  211.     call    inc_unsafe_flag
  212.     call    cs:old_int26    
  213.     call    dec_unsafe_flag 
  214.     ret ; user must pop flags - MS-DOS convention
  215.         ; so leave them on the stack
  216. _new_int26 endp
  217.  
  218. ;*****
  219. ;void far timer_int_chain(void) - jump to next timer ISR
  220. ;we need to clean up the stack because of this call
  221. ;*****
  222. _timer_int_chain proc far
  223.     mov _ax_save,ax
  224.     pop ax
  225.     pop ax
  226.     mov ax,_ax_save
  227.     jmp dword ptr _old_int8 
  228. _timer_int_chain    endp
  229. ENDIF
  230.  
  231. ;
  232. ;save areas for original interrupt vectors
  233. ;
  234. IFDEF MULTI
  235. old_int10   dd  0       ;video
  236. old_int25   dd  0       ;sector read
  237. old_int26   dd  0       ;sector write
  238. ENDIF
  239. old_int13   dd  0       ;disk
  240.  
  241. _ds_save    dw  0
  242. _TEXT   ends
  243.  
  244. _DATA   segment 
  245. IFDEF MULTI
  246. _ax_save dw 0
  247. ENDIF
  248. _DATA   ends
  249.  
  250.     end
  251.