home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR4 / V12N16.ZIP / FINDIR.ZIP / FINASM.ZIP / IRQMAIN.ASM < prev    next >
Assembly Source File  |  1993-08-24  |  36KB  |  799 lines

  1. ;---------------------------------------------------------------    
  2. ;irqmain.asm - Main module for FINDIRQ Utility                 |
  3. ;--------------------------------------------------------------|
  4. ;FINDIRQ Copyright (c) 1993                                    |
  5. ;                                                              |
  6. ;Rick Knoblaugh All rights reserved.                           |
  7. ;First Appeared in PC MAGAZINE, US Edition,                    |
  8. ;September 28, 1993                                            |
  9. ;--------------------------------------------------------------|
  10. ; 4/17/93                      Rick Knoblaugh                  |
  11. ;--------------------------------------------------------------|
  12. ;include files                                                 |
  13. ;---------------------------------------------------------------    
  14.                 include irqequ.inc
  15.                 include irqstruc.inc
  16.  
  17.  
  18.  
  19. bios_seg        segment at 0f000h
  20.                 org     0fffeh
  21. model_id        db      ?        
  22. bios_seg        ends
  23.  
  24.  
  25. code            segment public  'CODE'
  26.                 assume cs:code, ds:code, es:code
  27.  
  28. ;--------------------------------------------------------------
  29. ;externals                                                   |
  30. ;--------------------------------------------------------------
  31.  
  32.                 extrn   get_from_disk:near      ;irqsupt.asm
  33.                 extrn   put_to_disk:near        ;irqsupt.asm
  34.                 extrn   get_switch:near         ;irqsupt.asm         
  35.                 extrn   get_set_int:near        ;irqsupt.asm         
  36.                 extrn   get_path:near           ;irqsupt.asm         
  37.                 extrn   load_desc:near          ;irqsupt.asm
  38.                 extrn   find_devices:near       ;irqsupt.asm
  39.                 extrn   find_drivers:near       ;irqsupt.asm
  40.                 extrn   see_if_install:near     ;irqsupt.asm
  41.                 extrn   ck_for_dos:near         ;irqsupt.asm
  42.                 extrn   verify_enables:near     ;irqsupt.asm
  43.                 extrn   ck_monitor:near         ;irqsupt.asm
  44.                 extrn   get_stacks_seg:near     ;irqsupt.asm
  45.  
  46.                 extrn   int_1c_isr:near         ;irqisr.asm
  47.                 extrn   int_28_isr:near         ;irqisr.asm
  48.                 extrn   int_2f_isr:near         ;irqisr.asm
  49.                 extrn   old_1c_isr:near         ;irqisr.asm
  50.                 extrn   old_28_isr:near         ;irqisr.asm
  51.                 extrn   old_2f_isr:near         ;irqisr.asm
  52.                 extrn   atclassf:byte           ;irqisr.asm
  53.                 extrn   pic_mask:word           ;irqisr.asm
  54.                 extrn   read_pic_masks:near     ;irqisr.asm
  55.                 extrn   startup:near            ;irqisr.asm
  56.  
  57.                 extrn   disp_screen:near        ;irqdisp.asm
  58.                 extrn   cls_total:near          ;irqdisp.asm
  59.                 extrn   disp_pscreen:near       ;irqdisp.asm
  60.                 extrn   set_cursor:near         ;irqdisp.asm
  61.  
  62.  
  63. ;--------------------------------------------------------------
  64. ;publics                                                     |
  65. ;--------------------------------------------------------------
  66.                 public  data_path, data_file, installf
  67.                 public  start_util, int_table
  68.                 public  last_code, num_com, num_prt   
  69.                 public  pc_std_dev, at_std_dev
  70.                 public  pc_basic_dev, at_basic_dev 
  71.                 public  com3_desc, com4_desc
  72.                 public  other_desc, mouse_desc
  73.                 public  device_desc, int_tab_off, int_tab_seg
  74.                 public  FILE_NAME_LEN, dos_handler_seg     
  75.                 public  block_desc, drv_desc_ptr, drv_ptr   
  76.                 public  ver_irq_mask
  77.                 public  block_abbrv, monoflag, monoatrib
  78.                 public  dos_ver, math_present
  79.  
  80.     
  81. ;--------------------------------------------------------------
  82. ;Variables                                                    |
  83. ;--------------------------------------------------------------
  84.  
  85. data_path       db      MAX_PATHLEN dup(0)
  86. data_file       db      'FINDIRQ.DAT', 0
  87. FILE_NAME_LEN   equ     ($ - data_file)
  88.  
  89.  
  90.  
  91. int_table       isr_data        <1ch, int_1c_isr, old_1c_isr>
  92.                 isr_data        <28h, int_28_isr, old_28_isr>
  93.                 isr_data        <INSTALL_INT, int_2f_isr, old_2f_isr>
  94. INT_ENTRIES     equ     ($ - int_table)/ size isr_data
  95.  
  96. ;--------------------------------------------------------------
  97. ;Everything below here dropped when go TSR                    |
  98. ;--------------------------------------------------------------
  99. last_code       label   byte
  100.  
  101. installf        db      FALSE           ;TRUE if installed
  102. math_present    db      FALSE           ;TRUE if have coprocessor
  103.  
  104. cmd_table       cmd_dispatch <irq_help, HELP_SWITCH>    ;help for 'H' or
  105.                 cmd_dispatch <irq_help, HELP2_SWITCH>   ;help for '?'
  106.                 cmd_dispatch <irq_init, INIT_SWITCH>
  107.                 cmd_dispatch <irq_uninst, UNINST_SWITCH >
  108.                 cmd_dispatch <irq_tsr, TSR_SWITCH>
  109. MAX_SWITCHES    EQU     ($ - cmd_table) / size cmd_dispatch
  110.  
  111.  
  112. num_com         db      0       ;number of COM ports
  113. num_prt         db      0       ;number of printers                
  114. work_string     db      4 dup(?) ;used to format irq numbers
  115.  
  116. dos_handler_seg dw      0       ;segment for DOS stack handlers
  117. dos_ver         dw      0               
  118. drv_ptr         dd      ?       ;pointer to NUL device
  119.  
  120. ;
  121. ;The following word contains bits set corresponding to IRQs typically
  122. ;assigned to devices that may or may not be present.  If standard
  123. ;devices (such as COMn and LPn) are detected, bits corresponding to
  124. ;the IRQs used by such devices are turned off.  Any bits remaining on
  125. ;after we interrogate the system, represent IRQs that we should verify.
  126. ;For example, if an ill-behaved program enables IRQs in the PIC masks,
  127. ;but doesn't do anything with them (i.e. the vectors are still pointing
  128. ;to default handlers), we should not report these as active.
  129. ;
  130. ;
  131. ver_irq_mask    dw      ( ( (mask atirq15) or  (mask atmath) or (mask atirq12) or (mask atirq11) \
  132.                           (mask atirq10)) shl 8 or ( (mask atlpt1) or \
  133.                           (mask atlpt2) or (mask atcom1) or (mask atcom2) \
  134.                           or (mask atcas) ))
  135. monoflag        db      FALSE           ;TRUE if monochrome monitor
  136. monoatrib       db      FALSE           ;TRUE if should use B/W attributes
  137.  
  138. ;keep these together
  139. int_tab_off     dw      0       ;offset of int table in TSR code        
  140. int_tab_seg     dw      0       ;segment of int table in TSR code
  141.  
  142. ;--------------------------------------------------------------
  143. ;Data for screen displays                                     |
  144. ;--------------------------------------------------------------
  145.                 include irqsdata.inc
  146.         
  147. ;--------------------------------------------------------------
  148. start_util      proc    near
  149.                 cld                             ;all strings forward
  150.                 mov     ah, DOS_GET_VER         ;check unlikely event
  151.                 int     21h                     ;that user has really
  152.                 mov     dx, offset invalid_dos_msg
  153.  
  154. ;
  155. ;FINDIRQ requires DOS version 3.0 or better becuase it utilizes the
  156. ;information at the end of the DOS environment block which specifies
  157. ;the path for the process that owns the environment.
  158. ;
  159.                 cmp     al, 3                   ;need DOS 3.0 or better
  160.                 jae     start_u050
  161.                 jmp     start_u900              ;far jump
  162. start_u050:
  163.                 mov     cs:dos_ver, ax
  164.  
  165.                 mov     ax, bios_seg            ;look at ROM area
  166.                 mov     es, ax
  167.                 assume  es:bios_seg
  168.                 cmp     es:model_id, AT_MODEL   ;for AT model code
  169.                 je      start_u100
  170.                 cmp     es:model_id, PS2_AT     ;for PS/2 model code
  171.                 je      start_u100
  172.                 assume  es:nothing 
  173.                 mov     cs:atclassf, FALSE      ;XT or less
  174. start_u100:
  175.                 call    ck_monitor              ;determine if monochrome
  176.  
  177.                 call    get_path                ;get current path
  178.                 
  179.                 xor     si, si                  ;offset zero from psp
  180.                 sub     ch, ch
  181.                 mov     cl, [si].psp_cmd_len
  182.                 lea     si, [si].psp_cmd_tail
  183.                 call    get_switch
  184.                 mov     dx, offset invalid_swt_msg
  185.                 jc      start_u900
  186.  
  187.                 mov     bp, ax                  ;save switch
  188.  
  189. ;These 2 lines can be removed for .COM file
  190.                 push    cs                      
  191.                 pop     ds                      ;setup data segment
  192.  
  193.                 mov     pic_mask, 0ffffh        ;default to no IRQs active
  194.  
  195. ;Next, attempt to get PIC mask values from data file (it may not exist yet).
  196. ;
  197.                 push    cx                      ;save count of cmd line chars
  198.                 call    get_from_disk           ;attempt to read data file
  199.  
  200. ;Look at standard devices and alter PIC mask for those devices we
  201. ;know are present, but that may not be enabled (e.g. LPTn:, COMn:).
  202.                 call    get_init_pic            ;get PIC mask values
  203.                 call    get_stacks_seg          ;get segment of DOS STACKS
  204.                 pop     cx        
  205. ;At this point, cx=0 if no switch supplied on command line
  206.  
  207.                 jcxz    start_u140              ;jmp if no command line switch
  208.                 cmp     bp, NOVERIFY_SWITCH     ;/d option - don't verify enables?
  209.                 je      start_u160
  210.                 jmp     short start_u180        ;go process other switches
  211. start_u140:
  212.                 call    verify_enables          ;ensure IRQs really used
  213. start_u160:
  214.  
  215. ;Go get device descriptions for IRQs where devices are static 
  216. ;(e.g. IRQ0 is always used for the timer
  217. ;
  218.                 call    load_desc                   
  219.  
  220.              
  221.                 call    find_devices            ;look for other devices
  222.  
  223. ;If don't have descriptions for IRQs (i.e. device is some add-in
  224. ;board such as a sound board, SCSI adapter, etc.), go get the name of
  225. ;the driver or TSR to which the int is vectored.
  226. ;
  227.                 call    find_drivers             
  228.  
  229.  
  230.                 call    display_status
  231.                 jmp     short start_u999
  232.  
  233. start_u180:
  234. ;
  235.  
  236.                 mov     ax, bp                  ;get switch
  237.                 mov     cx, MAX_SWITCHES 
  238.                 mov     di, offset cmd_table 
  239. start_u200:
  240.                 cmp     al, [di].cmd_switch     ;switch found?
  241.                 je      start_u300              ;if so, go process
  242.                 add     di, size cmd_dispatch   ;advance to next entry
  243.                 loop    start_u200
  244.                 mov     dx, offset invalid_swt_msg ;bad switch message
  245.                 jmp     short start_u950        ;go display and exit
  246. start_u300:
  247.                 call    [di].cmd_routine        ;process per switch
  248.                 jmp     short start_u999
  249.  
  250.  
  251. start_u900:
  252.                 push    cs
  253.                 pop     ds                      ;get data segment
  254. start_u950:
  255.                 mov     ah, DOS_PRT_STRING       
  256.                 int     21h
  257. start_u999:
  258.                 mov     ax, (DOS_TERM SHL 8)    ;terminate
  259.                 int     21h
  260.                 ret
  261. start_util      endp        
  262.  
  263.  
  264. irq_help        proc    near 
  265.                 mov     si, offset help_screen
  266.                 call    disp_screen
  267.                 ret
  268. irq_help        endp
  269.  
  270. ;--------------------------------------------------------------
  271. ;irq_init - Utility has been invoked with the "/I" option.    |
  272. ;           Thus, user wants to overwrite any saved IRQ       |
  273. ;           information and reinitialize the IRQ data         |
  274. ;           file values for currently active IRQs.  This      |
  275. ;           would typically be done if a board has been       |
  276. ;           removed, or a jumper setting has been changed.    |
  277. ;                                                             |
  278. ;             Enter:                                          |
  279. ;                      ds = local data segment                |
  280. ;                 data_path=file spec for data file           |
  281. ;                                                             |
  282. ;                                                             |
  283. ;              Exit:                                          |
  284. ;                                                             |
  285. ;                 pic_mask updated                            |
  286. ;                                                             |
  287. ;                 Message is displayed.                       |
  288. ;                                                             |
  289. ;--------------------------------------------------------------
  290. irq_init        proc    near
  291.                 mov     pic_mask, 0ffffh        ;default to none active
  292.  
  293. ;Look at standard devices and alter our PIC mask for those devices we
  294. ;know are present, but may not be enabled (e.g. LPTn:, COMn:).
  295.                 call    get_init_pic            ;get PIC mask values
  296.  
  297.                 call    put_to_disk             ;write then to disk
  298.                 jnc     irq_init100
  299.                 mov     dx, offset io_err_msg   ;report i/o error
  300.                 jmp     short irq_init800
  301. irq_init100:
  302.                 mov     dx, offset init_msg     ;tell user we initialized it
  303. irq_init800:
  304.                 mov     ah, DOS_PRT_STRING       
  305.                 int     21h
  306. irq_init999:
  307.                 ret
  308. irq_init        endp
  309.  
  310.  
  311. irq_tsr         proc    near
  312. ;The following call returns with carry set if we are already installed
  313.                 call    see_if_install          ;detect our presence
  314.                 jnc     irq_tsr100
  315.                 mov     dx, offset tsr_already_msg 
  316.                 mov     ah, DOS_PRT_STRING       
  317.                 int     21h
  318.                 ret
  319. irq_tsr100:
  320.  
  321.                 mov     cx, INT_ENTRIES         ;number of ints to hook     
  322.                 mov     si, offset int_table    ;int routines etc.
  323. irq_tsr200:
  324.                 mov     al, [si].int_number     ;the interrupt to capture
  325.                 mov     di, [si].old_isr        ;place to store old &isr
  326.                 mov     dx, [si].isr_routine    ;our isr offset
  327.                 call    get_set_int             ;go install our isr
  328.                 add     si, size isr_data
  329.                 loop    irq_tsr200
  330.  
  331.                 mov     dx, offset tsr_ok_msg 
  332.                 mov     ah, DOS_PRT_STRING       
  333.                 int     21h
  334.  
  335.                 pop     ax                      ;clean up stack
  336.  
  337.                 mov     dx, cs
  338.                 mov     bx, dx
  339.                 inc     dx    
  340.                 mov     ax, offset last_code
  341.                 mov     cl, 4
  342.                 shr     ax, cl
  343.                 add     dx, ax
  344.                 sub     dx, bx                  ;paragraphs to keep
  345.                 mov     ax, (DOS_TSR_FUNC SHL 8) ;exit code 0      
  346.                 int     21h                     ;Go TSR
  347. irq_tsr         endp
  348.  
  349.  
  350.  
  351.  
  352. ;--------------------------------------------------------------
  353. ;get_init_pic - Looking at standard devices from equipment    |
  354. ;               list, reflect those devices as being enabled. |
  355. ;               Also, read current PIC mask values and        |
  356. ;               reflect any new ones.                         |
  357. ;                                                             |
  358. ;             Enter:                                          |
  359. ;                      ds = local data segment                |
  360. ;                atclassf = TRUE if AT class machine          |
  361. ;                                                             |
  362. ;                pic_mask will hold current values read       |
  363. ;                         from data file (or reinitilized     |
  364. ;                         values if called as a result of     |
  365. ;                         /I option).                         |
  366. ;                                                             |
  367. ;              Exit:                                          |
  368. ;                                                             |
  369. ;                 pic_mask and ver_irq_mask updated           |
  370. ;                                                             |
  371. ;                                                             |
  372. ;                                                             |
  373. ;                                                             |
  374. ;--------------------------------------------------------------
  375. get_init_pic    proc    near
  376.                 cmp     atclassf, TRUE          ;AT machine?
  377.                 je      get_init050
  378.                 and     ver_irq_mask.d_master, not (mask atlpt2) ;no need to verify this IRQ
  379.                 jmp     short get_init080
  380. get_init050:
  381.                 and     pic_mask.d_slave, not (mask atclock) ;ATs have clock
  382. get_init080:
  383.                 int     11h                     ;do equipment check
  384.                 push    ax                      ;save the flags
  385.  
  386.                 test    ax, mask math_co        ;math coprocessor present?        
  387.                 jz      get_init100
  388.                 mov     math_present, TRUE      ;if so, set flag
  389. get_init100:
  390.  
  391.                 and     ax, mask num_prt_bits   ;isolate printers
  392.                 mov     cl, num_prt_bits
  393.                 shr     ax, cl                  ;have number printers
  394.                 mov     num_prt, al             ;save number of printers
  395.                 jz      get_init200             ;no printers
  396.                 and     pic_mask.d_master, not (mask atlpt1) ;show it enabled
  397.                 and     ver_irq_mask.d_master, not (mask atlpt1) ;no need to verify this IRQ
  398.                 cmp     atclassf, TRUE          ;AT machine?
  399.                 jne     get_init200
  400.                 cmp     ax, 1                   ;if so, more than 1 lpt ?
  401.                 je      get_init200
  402.                 and     pic_mask.d_master, not (mask atlpt2) ;show it enabled
  403.                 and     ver_irq_mask.d_master, not (mask atlpt2) ;no need to verify this IRQ
  404. get_init200:
  405.                 pop     ax                      ;get back equipment flags
  406.  
  407.                 and     ax, mask num_com_bits   ;isolate com ports
  408.                 mov     cl, num_com_bits
  409.                 shr     ax, cl                  ;have number com ports
  410.                 mov     num_com, al             ;save number of com ports
  411.                 jz      get_init500             ;no com ports
  412.                 and     pic_mask.d_master, not (mask atcom1) ;show it enabled
  413.                 and     ver_irq_mask.d_master, not (mask atcom1) ;no need to verify this IRQ
  414.                 cmp     ax, 1                   ;more than 1 com ?
  415.                 je      get_init500
  416.                 and     pic_mask.d_master, not (mask atcom2) ;show it enabled
  417.                 and     ver_irq_mask.d_master, not (mask atcom2) ;no need to verify this IRQ
  418. get_init500:
  419.                 call    read_pic_masks
  420.                 ret
  421. get_init_pic    endp
  422.  
  423. ;--------------------------------------------------------------
  424. ;display_status - Display screen showing IRQs, use by         |
  425. ;                 standard devices, and use by this           |
  426. ;                 system.                                     |
  427. ;                                                             |
  428. ;                                                             |
  429. ;             Enter:                                          |
  430. ;                      ds = local data segment                |
  431. ;                                                             |
  432. ;                                                             |
  433. ;              Exit:                                          |
  434. ;                                                             |
  435. ;                                                             |
  436. ;--------------------------------------------------------------
  437. display_status  proc    near
  438.                 mov     bh, SCREEN_ATTRIB
  439.                 call    cls_total               ;clear screen first
  440.  
  441.                 mov     di, offset rep_top      ;top portion of display
  442.                 call    disp_pscreen            ;display top lines
  443.                 
  444.                 mov     dh, DISP_BEG_ROW        ;row display counter        
  445.                 mov     cx, 16                  ;max irqs
  446.                 cmp     atclassf, TRUE          ;AT machine?
  447.                 je      display_s100            ;if so, 16 IRQs
  448.                 shr     cx, 1                   ;else 8
  449. display_s100:
  450.                 push    cx                      ;save irq count
  451. display_s150:
  452.                 mov     det_line.str_rowp, dh   ;row for display
  453.                 mov     di, offset det_line 
  454.                 call    disp_pscreen
  455.  
  456.                 inc     dh                      ;advance row counter
  457.                 loop    display_s150
  458.  
  459.                 mov     bot_line.str_rowp, dh   ;row for display
  460.                 mov     di, offset bot_line 
  461.                 call    disp_pscreen            ;display bottom line
  462.                 
  463.                 pop     cx                      ;number of irqs
  464.  
  465.                 xor     al, al                  ;irq counter
  466.                 mov     bx, pic_mask            ;bl=mask master bh=mask slave
  467.                 mov     dh, DISP_BEG_ROW        ;row display counter        
  468.  
  469.                 push    ds
  470.                 pop     es                      ;get es=ds
  471.  
  472. display_s190:
  473.                 mov     wrk_line.str_rowp, dh
  474.                 mov     wrk_line.str_colp, COLUMN_IRQ  
  475.                 mov     wrk_line.str_attribp, DETAIL_ATTRIB
  476.                 mov     di, offset work_string
  477.                 mov     wrk_line.str_data_ptr, di    
  478.  
  479.                 push    ax                      ;save irq counter
  480.                 aam                             ;make irq number bcd
  481.                 add     ax, 3030h               ;make ASCII           
  482.                 cmp     ah, 30h                 ;< 10?
  483.                 jne     display_s200            ;if not, go move high order
  484.                 mov     ah, ' '
  485. display_s200:
  486.                 xchg    al, ah
  487.                 stosb
  488.                 xchg    al, ah
  489.                 stosb
  490.                 mov     byte ptr [di], STR_TERM
  491.  
  492.                 pop     ax                      ;restore irq counter
  493.  
  494.                 mov     di, offset wrk_line
  495.  
  496.                 shr     bx, 1                   ;get irq mask bit into carry
  497.  
  498.                 push    bx
  499.  
  500.                 lahf                            ;get flags
  501.                 jnc     display_s300            ;jmp if irq active
  502.                 cmp     al, 0dh                 ;math coprocessor
  503.                 je      display_s300            ;if so, it's reserved (not available)
  504.                 mov     wrk_line.str_attribp, FREE_ATTRIB   ;highlight indicating free
  505. display_s300:
  506.                 call    disp_pscreen
  507.  
  508. ;display device that normally uses this irq
  509.                 call    disp_std_dev            
  510.  
  511. ;display device that uses this irq on this system
  512.  
  513.                 call    disp_this_dev            
  514.  
  515.                 call    disp_use                ;display use status
  516.                 
  517.                 inc     dh                      ;advance row
  518.                 inc     al                      ;next irq
  519.                 pop     bx
  520.                 loop    display_s190
  521.  
  522. ;The following call returns with carry set if we are already installed
  523.                 call    see_if_install          ;detect our presence
  524.                 jnc     display_s800
  525.  
  526.                 mov     di, offset rel_line
  527.                 call    disp_pscreen            ;display them
  528.  
  529. display_s800:
  530.                 mov     di, offset press_esc    ;press esc and help message
  531.                 call    disp_pscreen            ;display them
  532.  
  533. display_s900:
  534.                 xor     al, al                  ;zero
  535.                 call    set_cursor              ;turn cursor off
  536. display_s950:
  537.                 sub     ah, ah
  538.                 int     16h                     ;get a key
  539.                 cmp     al, ESC_KEY
  540.                 jne     display_s950
  541.                 mov     al, 1                             
  542.                 call    set_cursor              ;turn cursor on 
  543.                 
  544.                 ret
  545. display_status  endp
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552. ;--------------------------------------------------------------
  553. ;disp_std_dev - Per the IRQ number, display device name that  |
  554. ;               normally uses that device.                    |
  555. ;                                                             |
  556. ;                                                             |
  557. ;             Enter:                                          |
  558. ;                      ds = local data segment                |
  559. ;                      al = irq number                        |
  560. ;                atclassf = true if AT class machine          |
  561. ;       wrk_line.str_rowp = row for display                   |  
  562. ;                                                             |
  563. ;              Exit:                                          |
  564. ;                                                             |
  565. ;                                                             |
  566. ;--------------------------------------------------------------
  567. disp_std_dev    proc    near
  568.                 sub     bh, bh
  569.                 mov     bl, al                  ;irq number
  570.                 shl     bx, 1                   ;index into words
  571.                 mov     wrk_line.str_colp, COLUMN_STD 
  572.                 mov     wrk_line.str_attribp, DETAIL_ATTRIB
  573.  
  574.                 mov     di, offset at_std_dev
  575.                 cmp     atclassf, TRUE          ;AT machine?
  576.                 je      disp_std_100
  577.                 mov     di, offset pc_std_dev
  578.  
  579. disp_std_100:
  580.                 mov     bx, [di + bx]           ;get ptr to description
  581.                 or      bx, bx                  ;is there a device here?
  582.                 jz      disp_std_999            ;if not, nothing to do
  583.  
  584.                 mov     di, offset wrk_line   
  585.                 mov     wrk_line.str_data_ptr, bx    
  586.                 call    disp_pscreen
  587.  
  588. disp_std_999:
  589.                 ret
  590. disp_std_dev    endp
  591.  
  592.  
  593. ;--------------------------------------------------------------
  594. ;disp_this_dev - Per the IRQ number, display device name that |
  595. ;                uses it on this system.  If not a std        |
  596. ;                device, display "other".                     |
  597. ;                                                             |
  598. ;             Enter:                                          |
  599. ;                      ds = local data segment                |
  600. ;                      al = irq number                        |
  601. ;                atclassf = true if AT class machine          |
  602. ;       wrk_line.str_rowp = row for display                   |  
  603. ;                      ah = flags (where carry set if irq     |
  604. ;              Exit:               is inactive)               |
  605. ;                                                             |
  606. ;   cx saved                                                  |
  607. ;--------------------------------------------------------------
  608. disp_this_dev   proc    near
  609.                 sub     bh, bh
  610.                 mov     bl, al                  ;irq number
  611.                 shl     bx, 1                   ;index into array 
  612.                 shl     bx, 1                   
  613.                 shl     bx, 1                   
  614.  
  615.                 mov     dl, COLUMN_THIS 
  616.                 
  617.                 mov     wrk_line.str_attribp, DETAIL_ATTRIB
  618.                 mov     di, offset device_desc
  619.  
  620.                 push    cx
  621.                 mov     cx, (size device_desc_off) / DESC_ENTRY ;number of descriptions
  622.  
  623. disp_this_100:
  624.                 cmp     [di + bx].d_segment, 0  ;more than 1 description?
  625.                 je      disp_this_125
  626.                 sub     dl, 2                   ;if so, start back little
  627. disp_this_125:
  628.  
  629.                 mov     bp, [di + bx]           ;get ptr to description
  630.                 sahf                            ;get flag indicating active
  631.                 jnc     disp_this_500           ;jmp if active
  632.                 or      bp, bp                  ;is there a description?
  633.                 jnz     disp_this_600           ;there is
  634.  
  635. disp_this_150:
  636.                 mov     bp, offset vacant_desc  ;if not, print "vacant"
  637. disp_this_500:
  638.                 or      bp, bp                  ;is there a description?
  639.                 jnz     disp_this_600           
  640.                 mov     bp, offset other_desc   ;if not, print "Other"
  641. disp_this_600:
  642.                 push    di
  643.                 mov     di, offset wrk_line    
  644.                 mov     wrk_line.str_data_ptr, bp    
  645.                 mov     wrk_line.str_colp, dl   ;column to start
  646.                 call    disp_pscreen
  647.                 pop     di
  648.                 inc     dl                      ;next column
  649.                 add     bx, DESC_ENTRY          ;next description
  650.                 mov     bp, [di + bx]           ;get ptr to next description
  651.                 cmp     bp, 0 
  652.                 loopne  disp_this_600
  653.  
  654. disp_this_999:
  655.                 pop     cx
  656.                 ret
  657. disp_this_dev   endp
  658.  
  659.  
  660. ;--------------------------------------------------------------
  661. ;disp_use - Per the IRQ number, display whether this irq      |
  662. ;           is in-use or free.                                |
  663. ;                                                             |
  664. ;             Enter:                                          |
  665. ;                      ds = local data segment                |
  666. ;                      al = irq number                        |
  667. ;                atclassf = true if AT class machine          |
  668. ;       wrk_line.str_rowp = row for display                   |  
  669. ;                      ah = flags (where carry set if irq     |
  670. ;              Exit:               is inactive)               |
  671. ;                                                             |
  672. ;                                                             |
  673. ;--------------------------------------------------------------
  674. disp_use        proc    near
  675.                 mov     wrk_line.str_colp, COLUMN_STATUS
  676.                 mov     wrk_line.str_attribp, DETAIL_ATTRIB
  677.                 mov     bx, offset inuse_desc   ;default to inuse
  678.                 sahf                            ;get flag indicating active
  679.                 jnc     disp_use_900            ;jmp if active
  680.                 mov     bx, offset free_desc 
  681.  
  682.                 cmp     al, 0dh                 ;math coprocessor
  683.                 jne     disp_use_500               
  684.  
  685.                 mov     bx, offset reserv_desc  ;if so, it's reserved
  686.                 jmp     short disp_use_900
  687.  
  688.  
  689. disp_use_500:
  690.                 mov     wrk_line.str_attribp, FREE_ATTRIB
  691.  
  692. disp_use_900:
  693.                 mov     di, offset wrk_line   
  694.                 mov     wrk_line.str_data_ptr, bx    
  695.                 call    disp_pscreen
  696.                 ret
  697. disp_use        endp
  698.  
  699. ;--------------------------------------------------------------
  700. ;irq_uninst - Use interrupt to determine if we are resident.  |
  701. ;             If resident, unhook used interrupts and         |
  702. ;             release memory.                                 |
  703. ;                                                             |
  704. ;             Enter:                                          |
  705. ;                      ds = local data segment                |
  706. ;              Exit:                                          |
  707. ;                      message displayed                      |
  708. ;                                                             |
  709. ;--------------------------------------------------------------
  710. irq_uninst      proc    near
  711.                 call    see_if_install          ;detect our presence
  712.                 mov     dx, offset not_install_msg
  713.                 jnc     irq_un900               ;exit if not installed        
  714.                                 
  715.                 call    vectors_same            ;anyone steal vectors?
  716.                 jc      irq_un800               ;if so, can't uninstall
  717.  
  718.                 call    restore_vectors
  719.  
  720.                 mov     ax, int_tab_seg         ;get our TSR PSP 
  721.                 mov     es, ax
  722.                 mov     bx, psp_environ_seg
  723.                 mov     ax, es:[bx]             ;get environment segment
  724.                 mov     es, ax
  725.                 mov     ah, DOS_RELEASE_MEM        
  726.                 int     21h
  727.                 jc      irq_un800               ;if error, report it
  728.  
  729.                 mov     ax, int_tab_seg         ;get our TSR PSP 
  730.                 mov     es, ax
  731.                 mov     ah, DOS_RELEASE_MEM        
  732.                 int     21h
  733.                 jc      irq_un800               ;if error, report it
  734.  
  735.                 mov     dx, offset uninst_ok_msg
  736.                 jmp     short irq_un900
  737. irq_un800:
  738.                 mov     dx, offset cant_un_msg
  739. irq_un900:
  740.                 mov     ah, DOS_PRT_STRING 
  741.                 int     21h
  742.                 ret
  743. irq_uninst      endp
  744.  
  745.  
  746. vectors_same    proc    near
  747.                 push    ds
  748.                 xor     bx, bx
  749.                 mov     es, bx                          ;vectors 
  750.                 mov     dx, int_tab_off.d_segment       ;get segment of our isr
  751.                 assume  ds:nothing
  752.                 lds     di, dword ptr int_tab_off       ;int table in TSR code
  753.                 mov     cx, INT_ENTRIES                 ;number of entries
  754. vectors_s100:
  755.                 mov     bl, [di].int_number 
  756.                 shl     bx, 1
  757.                 shl     bx, 1
  758.                 mov     ax, [di].isr_routine            ;offset to &isr
  759.                 cmp     ax, es:[bx].d_offset
  760.                 jne     vectors_s800
  761.                 cmp     dx, es:[bx].d_segment
  762.                 jne     vectors_s800
  763.                 add     di, size isr_data 
  764.                 loop    vectors_s100
  765.                 clc
  766.                 jmp     short vectors_s900
  767. vectors_s800:
  768.                 stc
  769. vectors_s900:
  770.                 pop     ds
  771.                 assume  ds:code
  772. vectors_s999:
  773.                 ret
  774. vectors_same    endp
  775.  
  776. restore_vectors proc    near
  777.                 push    ds
  778.                 les     si, dword ptr int_tab_off       ;int table in TSR code
  779.                 mov     cx, INT_ENTRIES                 ;number of entries
  780. restore_v200:
  781.                 mov     al, es:[si].int_number     ;the interrupt to restore
  782.                 mov     di, es:[si].old_isr     ;&variable holding &isr to restore
  783.                 mov     dx, es:[di].d_segment
  784.                 mov     ds, dx
  785.                 mov     dx, es:[di].d_offset 
  786.                 mov     ah, DOS_SET_INT         
  787.                 int     21h                     ;ds:dx has our routine
  788.                 add     si, size isr_data
  789.                 loop    restore_v200
  790.  
  791.                 pop     ds
  792.                 ret
  793. restore_vectors endp
  794.  
  795.  
  796. code            ends
  797.                 end     startup
  798.  
  799.