home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / showtsrs / showtsrs.asm next >
Assembly Source File  |  1988-09-29  |  63KB  |  1,173 lines

  1.           PAGE    60,132
  2.           TITLE   SHOWTSRS - Program to scroll MAPMEM data
  3.       ;
  4.       ; Author:  Tom Gilbert
  5.       ;          7127 Lafayette Ave.
  6.       ;          Kansas City, KS
  7.       ;          (913) 299-2701 
  8.       ; 
  9.       ; Use Microsoft Assembler v. 5.1 or Turbo Assembler v. 1.0
  10.       ; Requires DOS.INC and BIOS.INC from Microsoft Assembler package
  11.           ;
  12.           ; Assemble with TASM SHOWTSRS  then
  13.           ; Link with     TLINK SHOWTSRS
  14.           ;     OR
  15.           ;               MASM SHOWTSRS  then
  16.           ;               LINK SHOWTSRS
  17.           DOSSEG
  18.           .MODEL  small
  19.           INCLUDE dos.inc       ;From MASM package              
  20.           INCLUDE bios.inc      ;  "   "     "
  21.           .STACK  100h
  22.           .DATA
  23. headline  DB      "  Allocated Memory Map  -  Version 1.0  -  "
  24.           DB      " by Tom Gilbert's Heart&Mind",13,10
  25.           DB      "                         Syntax: > ShowTSRs"
  26.           DB      " [anything for HELP]",13,10
  27.           DB      " PSP  MCB  files bytes   owner     command line   "
  28.           DB      " chained/hooked INT vectors",13,10
  29.           DB      " ---- ---- ----- ----- --------- ---------------- "
  30.           DB      " --------------------------",13,10
  31. helpdat label   byte
  32. DB "                     ***** ShowTSRs HELP *****",13,10
  33. DB 13,10
  34. DB " ShowTSRs displays the map of memory blocks and interrupts",13,10
  35. DB " used by TurboPower Software DISABLE and RELEASE programs.",13,10,13,10
  36. DB " PSP is the Program Segment Prefix segment address of a program",13,10
  37. DB "     or the PSP segment address for an environment of a program",13,10
  38. DB 13,10
  39. DB " MCB is the Memory Control Block for either of the above and is",13,10
  40. DB "    always the paragraph preceeding the controlled memory block",13,10
  41. DB 13,10
  42. DB " Listings show a line for each MCB.  A Program's Environment is",13,10
  43. DB ' the first of equal PSP segments.  Program OPEN "files" include',13,10
  44. DB ' the 5 standard DOS devices.  Block lengths are decimal "bytes".',13,10
  45. DB 13,10
  46. DB " Because owner filenames are read from the end of a program's",13,10
  47. DB " environment copy, ShowTSRs requires DOS Version 3.0 or higher!",13,10
  48. DB ' Programs which release their environments are "command" except',13,10
  49. DB " for TurboPower's FMARK which has another known name location.",13,10
  50. DB 13,10
  51. DB " Command Line Parameters are reproduced for the first 16 bytes.",13,10
  52. DB " Those followed by an elipsis (...) exceed 16 bytes.",13,10,13,10
  53. DB ' Interrupts which are "chained" from program to program will be',13,10
  54. DB " displayed after WATCH is installed.  Otherwise, only vectors at",13,10
  55. DB ' the top of the chain (called "hooked" vectors) are displayed.',13,10
  56. DB 13,10
  57. DB " EGA Info 8 bytes and Inter-application Communication",13,10
  58. DB " Area 16 bytes are provided in HEX & ASCII dump format.",13,10,13,10
  59. DB " If expanded memory is installed, the Manager's Version number,",13,10
  60. DB " Page Frame Segment (through which memory is windowed) and block",13,10
  61. DB " information will be shown.  User programs providing a name will",13,10
  62. DB " have it displayed.",13,10
  63. DB "                    ***** End of ShowTSRs Help *****",13,10
  64. helplen equ $-helpdat
  65.  
  66. statline  DB      " Line:    of   "
  67. stathelp  DB      " Move:   PGUP PGDN HOME END or Use ESC key to"
  68. statfile  DB      " Exit: ShowTSRs "
  69. cmdparam  DB      " ",13
  70. datf      DB      0             ; Command flag 0 = Data else HELP
  71. spsp      DW      ?             ; Segment of ProgramSegmentPrefix
  72. tmem      DW      ?             ; Total Available Conventional RAM
  73. columns   EQU     80            ; Number of columns used per row
  74. rows      DW      24            ; Number of last row for display
  75. datrows   DW      20            ; Number of data rows per page
  76. lastrow   DW      24            ; Number of last display row
  77. cell      LABEL   WORD          ; Cell (character and attribute)
  78. char      DB      " "           ; Initialize to space
  79. attr      DB      ?             ; Attribute
  80. mode      DB      ?             ; Initial mode
  81. pag       DB      ?             ; Initial display page
  82. newvid    DB      0             ; Video change flag
  83. cga       DB      1             ; CGA flag - default yes
  84. vidadr    DW      0B800h        ; Video buffer address - default CGA
  85. mono      EQU     0B000h        ; Monochrome address
  86. statatr   DB      030h          ; Color default - black on cyan
  87. bwstat    EQU     070h          ; B&W default - black on white
  88. scrnatr   DB      017h          ; Color default - white on blue
  89. bwscrn    EQU     007h          ; B&W default - white on black
  90.  
  91. pbuffer   DW      0             ; Position in buffer (offset)
  92. sbuffer   DW      ?             ; Base of buffer (segment)
  93. lbuffer   DW      ?             ; Length of buffer
  94. linenum   DW      ?             ; Data buffer line
  95. lastnum   DW      ?             ; Last buffer line
  96. exkeys    DB      71,72,73,79,80,81     ; Extended key codes
  97. lexkeys   EQU     $-exkeys              ; Table of keys
  98. extable   DW      homek,upk,pgupk,endk,downk,pgdnk,nonek
  99.  
  100. EgaHdg  DB  " EGA Information Area at 0040:00A8 "
  101. EgaLen      equ $-EgaHdg
  102. IcaHdg  DB  " Inter-application Communications Area:",13,10," 0040:00F0 "
  103. IcaLen      equ $-IcaHdg
  104.  
  105. EmsName DB  "EMMXXXX0"          ; EMM standard Name
  106. tpages  DW  0                   ; Page accumulator
  107. emserm  DB  13,10,"   *** Expanded Memory NOT Installed or NOT Working ***"
  108. emerml  equ $-emserm
  109. emmshdg DB  " block    pages   KBytes   UserName    (Expanded Memory - Version "
  110. emmlen1 equ $-emmshdg
  111.         DB  ")",13,10
  112. dashes  DB  " -----    -----   ------   --------    (LIM page frame address - "
  113. emmlen2 equ $-emmshdg-emmlen1
  114. freem   DB  "  free"
  115. totlm   DB  " total"
  116. fmark   DB  "FM2.5 TSR"
  117. envcm   DB  "<environment>"
  118. doscm   DB  "DOSCVcommand <CONFIG.SYS>"
  119. disam   DB  "***  D I S A B L E D  ***"
  120. disalen equ $-disam
  121. WatchS  DB  "TSR WATCHER"               ; WATCH Command Line Parameter
  122. WatchF  DW  0                           ; MCB Index to WATCH PSP if Set
  123. startl  DW  0                           ; Destination Index at Start of a Line
  124. vpos    DW  ?                           ; WATCH Next PSP Position
  125. MCB     STRUC
  126. pspa    DW  0                           ; Program Segment Prefix or Mark Address
  127. mcba    DW  0                           ; Memory Allocation Block Address
  128. mcbl    DW  0                           ; Length in paragraphs to next MCB
  129. MCB     ENDS
  130. MCBS    MCB 100 DUP (<>)                ; Array of MCB Structures
  131.           .CODE
  132. Main        PROC
  133.             mov     ax,@data            ; Destination is data
  134.             mov     es,ax               ; flag with length of
  135.             mov     di,OFFSET datf      ; command line
  136.             mov     si,80h              ; parameter
  137.             movsb
  138.             mov     es:spsp,ds          ; Preserve PSP Segment
  139.             mov     ds,ax               ; Set Data Segment Register
  140.             cli                         ; Turn off interrupts
  141.             mov     ss,ax               ; Make SS and
  142.             mov     sp,OFFSET STACK     ;   SP relative to DGROUP
  143.             sti
  144.             mov     bx,sp               ; Convert stack pointer to
  145.             mov     cl,4                ; number of stack paragraphs
  146.             shr     bx,cl
  147.             add     ax,bx               ; Add SS to get end of program
  148.             sub     ax,spsp             ; Subtract start to get length
  149.             @ModBlok ax,spsp            ; Release memory after program
  150.             @GetBlok 0FFFFh             ; Request all remaining memory
  151.             mov     es,ax               ; Set Extra Segment Register
  152.             mov     sbuffer,ax          ; Save buffer segment and
  153.             mov     lbuffer,bx          ; actual length allocated
  154.             add     ax,bx               ; Calculate and store total
  155.             mov     tmem,ax             ; available conventional RAM
  156.             mov     di,pbuffer          ; Point to beginning and
  157.             @GetVer                     ; Get DOS version
  158.             cmp     al,3                ; If Version < 3.0
  159.             jc      HelpOpt             ; then provide HELP
  160.             test    datf,0FFh           ; Or If command parameter
  161.             jnz     HelpOpt             ; then provide HELP
  162.             call    WorkMCBs            ; Or If invalid MCBs
  163.             jc      HelpOpt             ; then provide HELP
  164.             call    InfoMap             ; else add info areas
  165.             mov     si,OFFSET EmsName   ; and EMS information
  166.             call    EmmsMap             ;  if EMS is installed
  167.             jmp     SHORT EndData
  168. HelpOpt:    mov     cmdparam,"?"        ; Show HELP requested
  169.             mov     si,OFFSET helpdat   ; and store help data
  170.             mov     cx,helplen
  171.             rep     movsb
  172. EndData:    call    EndCount            ; Count buffer
  173.             mov     ax,linenum          ; data lines and
  174.             mov     lastnum,ax          ; store the count
  175.             mov     lbuffer,di          ; and store length
  176.             call    Video               ; Adjust for mode & adapter
  177.             @SetCurPos 0,43             ; Hide cursor off screen
  178.             call    homek               ; Display 1st Page
  179.             mov     ax,datrows          ; If more data
  180.             sub     ax,lastnum          ; lines to show
  181.             jc      nextkey             ; then accept keys
  182.             dec     ax                  ; else modify
  183.             sub     lastrow,ax          ; last row and
  184.             jmp     SHORT quit          ; exit ShowTSRs
  185.  
  186. nextkey:    @GetKey 0,0,0               ; Get a key
  187.             cmp     al,0                ; If a null
  188.             je      extended            ; then Must be extended code
  189.             cmp     al,27               ; else If NOT ESCape
  190.             jne     nextkey             ; then Ignore unknown command
  191.  
  192. quit:       @FreeBlok sbuffer           ; else release buffer
  193.             cmp     newvid,1            ; If video not changed
  194.             jne     thatsall            ; then that's all
  195.             @SetMode mode               ; else Restore video mode,
  196.             @SetPage pag                ; page, and cursor
  197. thatsall:   mov     cx,lastrow          ; Load last row and
  198.             mov     ax,rows             ; Calculate rows to
  199.             sub     ax,cx               ; be scrolled blank
  200.             xchg    cl,ch               ; Set Upper Left and
  201.             mov     dx,cx               ; copy in order to
  202.             add     dh,al               ; adjust Lower Right
  203.             mov     dl,columns-1        ; corner of window
  204.             mov     ah,6                ; Call ROM BIOS to
  205.             mov     bh,7                ; clear the window
  206.             int     10h
  207.             mov     dx,cx               ; Set cursor above
  208.             dec     dh                  ; window so prompt
  209.             @SetCurPos                  ; is on last line
  210.             @Exit   0                   ; when Exit to DOS
  211.  
  212. extended:   @GetKey 0,0,0               ; Get extended code
  213.             push    es
  214.             push    ds                  ; Load DS into ES
  215.             pop     es
  216.             mov     di,OFFSET exkeys    ; Load address and
  217.             mov     cx,lexkeys+1        ; length of key list
  218.             repne   scasb               ; Find position
  219.             pop     es
  220.             sub     di,(OFFSET exkeys)+1; Point to key
  221.             shl     di,1                ; Adjust pointer for word addresses
  222.             call    extable[di]         ; Call appropriate procedure
  223.             jmp     nextkey
  224.  
  225. homek:      mov     pbuffer,0           ; HOME - Zero the buffer
  226.             mov     ax,pbuffer          ; position for 1st page
  227.             jmp     SHORT GoPage
  228. upk:        mov     ax,-1               ; UP - GoBack one line if room
  229.             jmp     SHORT GoPage
  230. pgupk:      mov     ax,datrows          ; PGUP - Page back
  231.             neg     ax                  ; Up to page lines
  232.             jmp     SHORT GoPage
  233.  
  234. endk:       mov     ax,lbuffer          ; END - Get last byte of file
  235.             mov     pbuffer,ax          ; Make it the file position
  236.             mov     ax,datrows          ; Go Backward enough
  237.             neg     ax                  ; lines for last page
  238.             jmp     SHORT GoPage
  239. downk:      mov     ax,1                ; GoForward 1 line if room
  240.             jmp     SHORT GoPage
  241. pgdnk:      mov     ax,datrows          ; PGDN - Go forward <= page
  242. GoPage:     push    ax
  243.             call    Pager
  244. nonek:      retn                        ; Ignore unknown key
  245. Main        ENDP
  246.  
  247. Video       PROC
  248.             push    es                  ; Preserve Extra Segment
  249.             mov     ah,12h              ; Call EGA status function
  250.             mov     bl,10h
  251.             sub     cx,cx               ; With Clear status bits
  252.             int     10h
  253.             sub     ax,ax               ; If status is still Clear
  254.             jcxz    modechk
  255.             mov     es,ax               ; or if EGA is NOT active
  256.             test    BYTE PTR es:[487h],1000b
  257.             jnz     modechk             ; then check CGA or Mono Mode
  258.             mov     ax,1130h            ; else get EGA information
  259.             int     10h
  260.             mov     al,dl               ; Make lines per screen
  261.             cbw                         ; into a Word Value
  262.             mov     rows,ax             ; Reset number of the
  263.             mov     lastrow,ax          ; last row and number
  264.             sub     ax,4                ; of rows available for
  265.             mov     datrows,ax          ; data from their defaults
  266.             dec     cga                 ; Clear the CGA Flag
  267. modechk:    pop     es                  ; Restore Extra Segment
  268.             @GetMode                    ; Get video mode
  269.             mov     mode,al             ; Save initial
  270.             mov     pag,bh              ; mode and page
  271.             mov     dl,al               ; Work on copy
  272.             cmp     dl,7                ; If mono 7
  273.             je      loadmono            ; then Set mono
  274.             cmp     dl,15               ; else if NOT mono 15
  275.             jne     graphchk            ; then Check graphics
  276. loadmono:   mov     vidadr,mono         ; else Load mono address
  277.             mov     statatr,bwstat      ; Set B&W defaults for status line
  278.             mov     scrnatr,bwscrn      ;   and screen background
  279.             dec     cga                 ; Set as NOT CGA
  280.             cmp     al,15               ; If NOT mono 15
  281.             jne     VidExit             ; then Done
  282.             mov     dl,7                ; else Set standard mono
  283.             jmp     SHORT chmode
  284. graphchk:   cmp     dl,7                ; 7 or higher?
  285.             jg      color               ; 8 to 14 are color (7 and 15 done)
  286.             cmp     dl,4                ; 4 or higher?
  287.             jg      bnw                 ; 5 and 6 are probably black and white
  288.             je      color               ; 4 is color
  289.             test    dl,1                ; Even?
  290.             jz      bnw                 ; 0 and 2 are black and white
  291. color:      cmp     dl,3                ; If mode 3
  292.             je      VidExit             ; then Done
  293.             mov     dl,3                ; else use color text mode
  294.             jmp     SHORT chmode
  295. bnw:        mov     statatr,bwstat      ; Set B&W defaults for status line
  296.             mov     scrnatr,bwscrn      ;   and screen background
  297.             cmp     dl,2                ; If mode 2
  298.             je      VidExit             ; then Done
  299.             mov     dl,2                ; else use B&W text mode
  300. chmode:     @SetMode dl                 ; Set video mode
  301.             @SetPage 0                  ; Set video page
  302.             mov     newvid,1            ; Set flag
  303. VidExit:    ret
  304. Video       ENDP
  305.  
  306. ; Procedure EndCount - Go backward to count lines in file
  307. ; Input     ES:DI has buffer position
  308. ; Output    Modifies "linenum"
  309.  
  310. EndCount    PROC
  311.             push    di
  312.             std                         ; Go backwards to
  313.             mov     al,13               ; Search for CR
  314.             mov     linenum,0           ; Initialize line count
  315. findstrt:   mov     cx,0FFh             ; Load maximum character count
  316.             cmp     cx,di               ; If NOT Near start of buffer
  317.             jl      notnear2            ; then use maximum count
  318.             mov     cx,di               ; else search
  319.             jcxz    found               ; only to start
  320. notnear2:   repne   scasb               ; If previous CR NOT found
  321.             jcxz    found               ; then must be at start
  322.             inc     linenum             ; else adjust line count
  323.             jmp     SHORT findstrt      ;  and continue search
  324. found:      pop     di                  ; Restore index
  325.             cld                         ; and direction
  326.             ret
  327. EndCount    ENDP
  328.  
  329. ; Procedure Pager - Displays status and text lines
  330. ; Input     Stack variable: lines to scroll (negative up, positive down)
  331. ; Output    Displays lines between first and last to screenn
  332.  
  333. Pager       PROC
  334.             push    bp
  335.             mov     bp,sp
  336.             mov     di,pbuffer          ; Index to buffer position
  337.             mov     cx,[bp+4]           ; Get count argument for
  338.             mov     ax,10               ; linefeeds to count and
  339.             or      cx,cx               ; If No lines to count
  340.             jz      show                ; then show the page
  341.             jg      forward             ; else Count Forward
  342.             call    GoBack              ; or Backward if neg
  343.             jmp     SHORT show          ; before showing page
  344. forward:    call    GoForwd
  345. show:       call    EndCount            ; Count to first
  346.             mov     ax,linenum          ; line number to show
  347.             add     ax,datrows          ; Adjust to bottom line
  348.             cmp     ax,lastnum          ; If NOT past last
  349.             jle     lineok              ; then number is ok
  350.             mov     ax,lastnum          ; else make it last
  351. lineok:     push    ds                  ; Set data segment into
  352.             pop     es                  ; extra segment register
  353.             push    ax                  ; Arg 1 - IntegerLSW
  354.             xor     ax,ax
  355.             push    ax                  ; Arg 2 - IntegerMSW
  356.             mov     ax,OFFSET statline[6]
  357.             push    ax                  ; Arg 3 - Destination
  358.             mov     ax,3
  359.             push    ax                  ; Arg 4 - Decimal Places
  360.             call    BinToDStr           ; Convert to string
  361.             mov     ax,lastnum
  362.  
  363.             push    ax                  ; Arg 1 - IntegerLSW
  364.             xor     ax,ax
  365.             push    ax                  ; Arg 2 - IntegerMSW
  366.             mov     ax,OFFSET statline[12]
  367.             push    ax                  ; Arg 3 - Destination
  368.             mov     ax,3
  369.             push    ax                  ; Arg 4 - Decimal Places
  370.             call    BinToDStr           ; Convert to string
  371.             mov     es,sbuffer          ; Restore ES to sbuffer
  372.             mov     bl,statatr          ; Set attribute for
  373.             mov     BYTE PTR cell[1],bl ; status & headings
  374.             xor     bx,bx               ; Initialize counter
  375.             mov     si,OFFSET headline  ; for heading lines
  376. hdloop:     push    bx                  ; Preserve counter
  377.             push    ds                  ; Arg 1 - Segment
  378.             push    si                  ; Arg 2 - Offset
  379.             push    bx                  ; Arg 3 - Display Line
  380.             push    cell                ; Arg 4 - Char/Attrib
  381.             call    CellWrt             ; Write one
  382.             push    ss                  ; Restore DGroup
  383.             pop     ds                  ; into DS register
  384.             pop     bx                  ; Restore line count and
  385.             mov     si,ax               ; get returned position
  386.             inc     bx                  ; Count the heading line
  387.             cmp     bx,4                ; If NOT yet 4 lines
  388.             jc      hdloop              ; then loop until 4
  389.             mov     al,scrnatr          ; Change attribute for
  390.             mov     BYTE PTR cell[1],al ; data buffer display
  391.             mov     si,pbuffer          ; Index to pbuffer
  392. datloop:    push    bx                  ; Preserve counter
  393.             push    sbuffer             ; Arg 1 - Segment
  394.             push    si                  ; Arg 2 - Offset
  395.             push    bx                  ; Arg 3 - Display Line
  396.             push    cell                ; Arg 4 - Char/Attrib
  397.             call    CellWrt             ; Write line
  398.             push    ss                  ; Restore DGroup
  399.             pop     ds                  ; into DS register
  400.             pop     bx                  ; Restore counter and
  401.             inc     bx                  ; Count row displayed
  402.             cmp     ax,lbuffer          ; If position => end
  403.             jnc     pagedone            ; then page is done
  404.             mov     si,ax               ; else update pointer
  405.  
  406.             cmp     bx,rows             ; If short of last row
  407.             jc      datloop             ; then loop Until done
  408. pagedone:   mov     al,statatr          ; Load attribute for
  409.             mov     BYTE PTR cell[1],al ; writing status line
  410.             mov     si,OFFSET statline
  411.             push    ds                  ; Arg 1 - Segment
  412.             push    si                  ; Arg 2 - Offset
  413.             push    bx                  ; Arg 3 - Display Line
  414.             push    cell                ; Arg 4 - Char/Attrib
  415.             call    CellWrt             ; Write status line
  416.             mov     es,sbuffer          ; Restore ES to buffer
  417.             pop     bp                  ; Discard stack
  418.             ret     2                   ; count argument
  419. Pager       ENDP
  420.  
  421. ; Procedure Retrace
  422. ; Purpose   Writes cell during horizontal retrace (CGA)
  423. ; Input     ES:DI has screen buffer position, AX has cell
  424. ; Output    Character to screen buffer
  425.  
  426. Retrace     PROC
  427.             push    bx
  428.             mov     bx,ax               ; Save character
  429. lscan2:     in      al,dx               ; Look in the port
  430.             shr     al,1                ;   until it goes low
  431.             jc      lscan2
  432.             cli
  433. hscan2:     in      al,dx               ; Look in the port
  434.             shr     al,1                ;   until it goes high
  435.             jnc     hscan2
  436.             mov     ax,bx               ; Restore and write it
  437.             stosw
  438.             sti
  439.             pop     bx
  440.             ret
  441. Retrace     ENDP
  442.  
  443. ; Procedure CellWrt - Writes a line to screen buffer
  444. ; Input     Stack variables (segment,offset,line,cell)
  445. ; Output    Line to screen buffer
  446.  
  447. CellWrt     PROC
  448.             push    bp
  449.             mov     bp,sp
  450.             sub     dx,dx               ; Clear as flag for scan
  451.             cmp     cga,1               ; CGA?
  452.             jne     noscan
  453.             mov     dx,03DAh            ; Load port #
  454. noscan:     mov     es,vidadr           ; Load screen buffer segment
  455.             mov     ds,[bp+10]          ; Buffer segment
  456.             mov     si,[bp+8]           ; Buffer position
  457.             mov     cx,80               ; Cells per row
  458.             mov     ax,[bp+6]           ; Starting row
  459.             mov     bx,80*2             ; Bytes per row
  460.             mul     bl                  ; Figure columns per row
  461.             mov     di,ax               ; Load as destination
  462.             mov     ax,[bp+4]           ; Set Attribute
  463. movechar:   lodsb                       ; Get character
  464.             cmp     al,13               ; If End of Data Line
  465.             je      fillspc             ; then end display line
  466.             or      dx,dx               ; else if NOT CGA
  467.             je      notCGA              ; then Write without delay
  468.             call    Retrace             ; else Write during retrace
  469.             loop    movechar            ; until End of Data Line
  470.             jmp     SHORT nextline      ; or end of display line
  471. notCGA:     stosw
  472.             loop    movechar            ; If end of display line
  473.             jmp     SHORT nextline      ; then find End of Data Line
  474. fillspc:    mov     al," "              ; Fill with space
  475.             or      dx,dx               ; If NOT CGA
  476.             je      space2              ; then direct
  477. space1:     call    Retrace             ; else Write during retrace
  478.             loop    space1              ; until end of display line
  479.             inc     si                  ; Adjust for Data line LF
  480.             jmp     SHORT exit          ; Done
  481. space2:     rep     stosw               ; Write
  482.             inc     si                  ; Adjust for LF
  483.             jmp     SHORT exit          ; Done
  484. nextline:   mov     ah,10               ; Search for Data line feed
  485. chklf:      lodsb                       ; Load and compare
  486.             cmp     al,ah               ; If NOT Data Line LF
  487.             loopne  chklf               ; then contine until
  488. exit:       mov     ax,si               ; Return position
  489.             pop     bp
  490.             ret     8
  491. CellWrt     ENDP
  492.  
  493. ; Procedure Search Backward or Forward through buffer
  494. ; Input     CX has number of lines; ES:DI has buffer position
  495. ; Output    Updates "pbuffer" and DI index
  496.  
  497. GoBack      PROC
  498.             std                         ; Go backward
  499.             neg     cx                  ; Make count positive
  500.             inc     cx                  ; Use one extra going up
  501. findb:      push    cx                  ; Preserve counter
  502.             mov     cx,0FFh             ; Load maximum character count
  503.             cmp     cx,di               ; If NOT near start of buffer
  504.             jc      scanb               ; then use maximum count
  505.             mov     cx,di               ; else search only to start
  506. scanb:      repne   scasb               ; If previous LF NOT found
  507.             jcxz    atstart             ; then must be at start
  508.             pop     cx                  ; else loop until start/done
  509.             loop    findb
  510.             add     di,2                ; Adjust for cr/lf
  511.             jmp     SHORT GoBackX       ; Return position
  512. atstart:    pop     cx
  513.             sub     di,di               ; Set index and
  514. GoBackX:    mov     pbuffer,di          ; pointer and
  515.             ret                         ; Return position
  516. GoBack      ENDP
  517. GoForwd     PROC
  518.             cld                         ; Go forward
  519. findf:      mov     pbuffer,cx          ; Preserve count
  520.             mov     cx,0FFh             ; Load maximum character count
  521.             repne   scasb               ; If next LF NOT found
  522.             jcxz    atend               ; then must be at end
  523.             mov     cx,pbuffer          ; else If past end
  524.             cmp     di,lbuffer          ; then make at end
  525.             jae     atend               ; else loop until
  526.             loop    findf               ; at end or found
  527.             mov     pbuffer,di
  528.             call    EndCount            ; Get line number
  529.             mov     cx,lastnum          ; If last number
  530.             sub     cx,datrows          ; minus display
  531.             cmp     cx,linenum          ; is => linenum
  532.             jnc     GoForX              ; then pbuffer Ok
  533. atend:      mov     di,lbuffer          ; Set index to end
  534.             mov     cx,datrows          ; Set page lines to
  535.             neg     cx                  ; back-up during
  536.             mov     al,10               ; GoBack procedure
  537.             call    GoBack
  538. GoForX:     ret                         ; Return pbuffer
  539. GoForwd     ENDP
  540.  
  541. ; Procedure BinToDStr Converts integer to right-justified decimal string
  542. ; Input     Stack arguments: (integerLSW,integerMSW,near-address,places)
  543. ; Output    BX:DX has leading:significant places written
  544.  
  545. BinToDStr   PROC
  546.             push    bp
  547.             mov     bp,sp
  548.             mov     ax,[bp+10]          ; Arg 1 (LSW)
  549.             mov     dx,[bp+8]           ; Arg 2 (MSW)
  550.             mov     di,[bp+6]           ; Arg 3 (addr)
  551.             sub     cx,cx               ; Clear counter
  552.             mov     bx,10               ; Divide by 10
  553. getdigit:   div     bx                  ; Get last digit as remainder
  554.             add     dl,"0"              ; Convert to ASCII
  555.             push    dx                  ; Save on stack
  556.             sub     dx,dx               ; Clear top
  557.             or      ax,ax               ; Until Quotient
  558.             loopnz  getdigit            ; becomes zero
  559.             neg     cx                  ; Negate and
  560.             mov     bx,cx               ; save count
  561.             mov     dx,[bp+4]           ; Arg 4 (places)
  562.             sub     dx,bx               ; If <= 0 to go
  563.             jle     putdigit            ; then abort
  564.             mov     cx,dx               ; else fill leading
  565.             or      al," "              ; places with spaces
  566.             rep     stosb
  567.             mov     cx,bx               ; Restore count
  568. putdigit:   pop     ax                  ; Add digit
  569.             stosb                       ; characters
  570.             loop    putdigit
  571.             mov     ax,[bp+4]           ; Return digit counts
  572.             sub     ax,bx               ; leading/significant
  573.             pop     bp                  ; Discard stack
  574.             ret     8                   ; parameters
  575. BinToDStr   ENDP
  576.  
  577. Val2ASCh    PROC
  578.             mov     ah,al               ; Preserve byte value
  579.             and     al,0F0h             ; Isolate high
  580.             shr     al,1                ; nibble
  581.             shr     al,1                ; into
  582.             shr     al,1                ; low
  583.             shr     al,1                ; nibble
  584.             call    Val2Dig             ; Convert to and
  585.             stosb                       ; store ASCII HEX
  586.             mov     al,ah               ; Restore byte value
  587.             and     al,0Fh              ; Isolate low nibble
  588. Val2Dig:    add     al,30h              ; Convert to display
  589.             cmp     al,3Ah              ; If decimal digit
  590.             jc      V2DX                ; then ASCII numeral
  591.             add     al,7                ; else make HEX alpha
  592. V2DX:       ret
  593. Val2ASCh    ENDP
  594.  
  595. PgsAndKbs   PROC
  596.             push    ax                  ; Preserve PagesLSW
  597.             xor     dx,dx               ; Clear PagesMSW
  598.             mov     bx,9                ; Set digit places
  599.             push    ax                  ; Arg 1 - PagesLSW
  600.             push    dx                  ; Arg 2 - PagesMSW
  601.             push    di                  ; Arg 3 - destination
  602.             push    bx                  ; Arg 4 - digit places
  603.             call    BinToDStr           ; Store decimal pages
  604.             pop     ax                  ; Restore PagesLSW
  605.             xor     dx,dx               ; Clear Extension
  606.             mov     bx,16               ; Convert Pages to
  607.             mul     bx                  ; KiloBytes LSW & MSW
  608.             mov     bx,9                ; Set digit places
  609.             push    ax                  ; Arg 1 - KiloByteLSW
  610.             push    dx                  ; Arg 2 - KiloByteMSW
  611.             push    di                  ; Arg 3 - destination
  612.             push    bx                  ; Arg 4 - digit places
  613.             call    BinToDStr           ; Store decimal KiloBytes
  614.             ret
  615. PgsAndKbs   ENDP
  616.  
  617. SortMCBs    PROC
  618.             push    cx                  ; Preserve PSP Counter
  619.             push    bx                  ; and MCB Index Pointer
  620.             dec     cx                  ; Set Compare Counter
  621. SLoop:      add     bx,6                ; Advance MCB Index
  622.             mov     ax,MCBS[bx].mcbl    ; Store
  623.             mov     MCBS.mcbl,ax        ; length
  624.             mov     ax,MCBS[bx].mcba    ; MCB
  625.             mov     MCBS.mcba,ax        ; and
  626.             mov     ax,MCBS[bx].pspa    ; PSP addresses in
  627.             mov     MCBS.pspa,ax        ; base array member
  628.             cmp     ax,MCBS[bx+6].pspa  ; If PSPs Ascending
  629.             jle     LoopS               ; then loop until done
  630.             mov     ax,MCBS[bx+6].pspa  ; else
  631.             mov     MCBS[bx].pspa,ax    ; swap
  632.             mov     ax,MCBS[bx+6].mcba  ; the
  633.             mov     MCBS[bx].mcba,ax    ; data
  634.             mov     ax,MCBS[bx+6].mcbl  ; for
  635.             mov     MCBS[bx].mcbl,ax    ; the
  636.             mov     ax,MCBS.mcbl        ; two
  637.             mov     MCBS[bx+6].mcbl,ax  ; array
  638.             mov     ax,MCBS.mcba        ; members
  639.             mov     MCBS[bx+6].mcba,ax  ; that
  640.             mov     ax,MCBS.pspa        ; were
  641.             mov     MCBS[bx+6].pspa,ax  ; compared
  642. LoopS:      loop    SLoop               ; until all compared
  643.             mov     al," "              ; Use Spaces to
  644.             mov     cx,lbuffer          ; fill data buffer
  645.             push    di                  ; Preserve pointer
  646.             rep     stosb               ; before filling and
  647.             pop     di                  ; Restore Pointer
  648.             pop     bx                  ; Restore MCB Index
  649.             pop     cx                  ; and PSP Counter
  650.             ret                         ; MCBS[0] last PSP
  651. SortMCBs    ENDP
  652.  
  653. IsEnviron   PROC
  654.             mov     cx,MCBS[bx].mcba    ; Convert Environment
  655.             inc     cx                  ; MCBA to Environment
  656.             mov     es,cx               ; Set-Up Segment:Index to
  657.             xor     di,di               ; search through
  658.             mov     ax,MCBS[bx].mcbl    ; Environment Length
  659.             mov     cx,4                ; multiplied by 16 to
  660.             shl     ax,cl               ; convert to bytes
  661.             sub     cl,4                ; for a double null
  662.             xchg    ax,cx
  663. SearchL:    repne   scasb               ; If counter runs out
  664.             jcxz    NoFname             ; then NOT environment
  665.             dec     cx                  ; else if double-null
  666.             scasb                       ; is NOT found before
  667.             jcxz    NoFname             ; counter has NOT run out
  668.             jne     SearchL             ; then loop until either
  669.             mov     al,"."              ; Search for an extent
  670.             repne   scasb               ; If extent NOT found
  671.             jne     NoFname             ; then copy "DOScommand"
  672.             sub     di,2                ; else isolate filename
  673.             mov     cx,10               ; Set Owner Area Length
  674. FnameLp:    cmp     BYTE PTR es:[di],":"; If character
  675.             jz      NameEnd             ; is drive
  676.             cmp     BYTE PTR es:[di],"\"; or directory
  677.             jz      NameEnd             ; then filename done
  678.             dec     di                  ; else backup to
  679.             loop    FnameLp             ; next character
  680. NoFname:    push    ds                  ; Put Data Segment into
  681.             pop     es                  ; Extra Segment Register
  682.             mov     di,OFFSET doscm+2   ; Point short of "DOScommand"
  683. NameEnd:    inc     di                  ; Point to 1st
  684.             mov     si,di               ; source character
  685.             push    ds                  ; Preserve Data Segment
  686.             push    es                  ; Transfer ES after
  687.             mov     es,sbuffer          ; Restoring Buffer Segment
  688.             pop     ds                  ; into DS Register and
  689.             mov     di,bp               ; Restore MapData Pointer
  690.             mov     dx,10               ; Calculate
  691.             sub     dx,cx               ; filename
  692.             xchg    dx,cx               ; length and
  693.             rep     movsb               ; store Owner and
  694.             add     di,dx               ; space to command line
  695.             pop     ds                  ; Restore Data Segment
  696.             mov     si,OFFSET envcm     ; Point to "<environment>"
  697.             mov     cx,13               ; Store its length
  698.             rep     movsb               ; into command line and
  699.             add     di,6                ; advance to vectors
  700.             ret
  701. IsEnviron   ENDP
  702. IsProgram   PROC
  703.             push    ax                  ; Preserve PSP and
  704.             push    bx                  ; MCBS Index Pointer
  705.             sub     bx,6                ; Backup to Environment MCB
  706.             call    IsEnviron           ; Get Owner Information
  707.             mov     cx,19               ; Backup to
  708.             sub     di,cx               ; Command and
  709.             mov     al," "              ; Space-It-Out
  710.             rep     stosb
  711.             sub     di,20               ; Restore Data
  712.             pop     bx                  ; Pointer, MCBS
  713.             pop     ax                  ; Index and PSP
  714.             ret
  715. IsProgram   ENDP
  716.  
  717. OwnComVec   PROC
  718.             push    cx                  ; Preserve StoLoop Counter
  719.             inc     di                  ; Advance and save
  720.             mov     bp,di               ; pointer to Owner
  721.             mov     ax,MCBS[bx].pspa    ; Get this MCB's PSP
  722.             cmp     bx,24               ; If MCB => 4th
  723.             jnc     CkEnvir             ; then check if Environment
  724.             cmp     ax,MCBS[bx-6].pspa  ; else if same as last PSP
  725.             je      IsEnvir             ; then IS DOS Environment
  726.             cmp     ax,8                ; else if NOT CONFIG.SYS
  727.             jne     Ck4Mark             ; then fall through to command
  728.             mov     si,OFFSET doscm     ; else IS DOS configuration
  729.             mov     cx,3                ; copy
  730.             rep     movsb               ; "DOS"
  731.             add     di,7                ; Advance
  732.             add     si,10               ; Pointers
  733.             mov     cx,12               ; copy
  734.             rep     movsb               ; "<CONFIG.SYS>"
  735.             jmp     OCVExit             ; and End the Line
  736.  
  737. IsEnvir:    mov     si,OFFSET doscm+5   ; Owner is
  738.             mov     cx,7                ; "command"
  739.             rep     movsb               ; copy and
  740.             add     di,3                ; Advance
  741.             mov     cx,13               ; pointer for
  742.             mov     si,OFFSET envcm     ; "<environment>"
  743.             rep     movsb               ; as command line
  744.             jmp     OCVExit             ; and End the Line
  745.  
  746. CkEnvir:    cmp     ax,MCBS[bx+6].pspa  ; If NOT same as next
  747.             jne     CkYour6             ; then check behind
  748.             call    IsEnviron           ; else IS Environment
  749.             jmp     SHORT OCVExit
  750. CkYour6:    cmp     ax,MCBS[bx-6].pspa  ; If NOT same as last
  751.             jne     Ck4Mark             ; then check for FMark
  752.             call    IsProgram           ; else IS Program PSP
  753.             push    ds                  ; Preserve Data Segment
  754.             mov     ds,ax               ; Set to PSP and
  755.             jmp     SHORT CmdParm       ; Get Command Line
  756. Ck4Mark:    push    ds                  ; Preserve Data Segment
  757.             mov     es,ax               ; Point into PSP at
  758.             mov     di,60h              ; FMark signature area
  759.             mov     si,OFFSET fmark     ; If FMark
  760.             mov     cx,9                ; signature
  761.             rep     cmpsb               ; bytes match
  762.             je      IsFMark             ; then is FMark
  763.             pop     ds                  ; else Restore Data and
  764.             mov     es,sbuffer          ; MapData Buffer Segments
  765.             mov     di,bp               ; Restore MapData Pointer
  766.             mov     si,OFFSET doscm+5   ; Point to "command"
  767.             mov     cx,7                ; bytes and copy to
  768.             rep     movsb               ; Owner Area of MapData
  769.             add     di,2                ; Advance to Command Line
  770.             push    ds                  ; Preserve Data Segment
  771.             mov     ds,ax               ; Set to PSP and
  772.             jmp     SHORT CmdParm       ; Get Command Line
  773. IsFMark:    push    es                  ; Put PSP Segment AFTER
  774.             mov     es,sbuffer          ; Restore MapData Buffer
  775.             pop     ds                  ; into DS Register
  776.             mov     si,di               ; Set Source Index to
  777.             mov     cx,9                ; beginning of the
  778.             sub     si,cx               ; FMark signature
  779.             mov     di,bp               ; Segment and Pointer
  780.             rep     movsb               ; Copy FMark Signature
  781. CmdParm:    mov     si,80h              ; Point to Command Length
  782.             lodsb                       ; Convert Parameter
  783.             cbw                         ; Length to Word
  784.             mov     cx,19               ; Set length to Vectors
  785.             xchg    ax,cx               ; and length of Command
  786.             sub     ax,cx               ; Calculate difference
  787.             cmp     cx,16               ; If command <= 16
  788.             jle     CopyCmd             ; then copy all bytes
  789.             mov     cx,16               ; else copy 16 bytes
  790.             mov     ax,".."             ; adding continuation
  791. CopyCmd:    rep     movsb               ; If copied parameter
  792.             cmp     ax,".."             ; is NOT continuation
  793.             jne     Go2Vecs             ; then adjust to Vectors
  794.             stosw                       ; else use continuation
  795.             stosb                       ; elipsis (...) and
  796.             xor     ax,ax               ; no further spaces
  797. Go2Vecs:    add     di,ax               ; Adjust DI to Vectors
  798.             pop     ds                  ; Restore Data Segment
  799.             mov     ax,MCBS[bx].mcba    ; If Memory Control Block
  800.             inc     ax                  ; Segment Address + 1
  801.             cmp     ax,MCBS[bx].pspa    ; is NOT EQUAL to PSP
  802.             jne     OCVExit             ; then NO Interrupts
  803.             call    Vectors             ; else store vectors
  804. OCVExit:    mov     ax,0A0Dh            ; End the Data
  805.             stosw                       ; Storage Line
  806.             pop     cx                  ; Restore StoLoop Counter
  807.             ret
  808. OwnComVec   ENDP
  809.  
  810. WorkMCBs    PROC
  811.             mov     ah,52h              ; Use reserved DOS
  812.             int     21h                 ; Interrupt to get
  813.             mov     bx,es:[bx-2]        ; Start MCB Address
  814.             xor     cx,cx               ; Zero Array Counter
  815. MCBLoop:    mov     es,bx               ; Locate MCB Segment
  816.             mov     bx,es:[3]           ; Input length to next
  817.             mov     dx,es:[1]           ; from PSP Address
  818.             or      dx,dx               ; If NO PSP Address
  819.             jz      CkBlock             ; then check MCB ID
  820.             inc     cx                  ; else advance counter
  821.             mov     ax,6                ; calculate
  822.             mul     cl                  ; and set
  823.             mov     bp,ax               ; MCB index
  824.             mov     MCBS[bp].pspa,dx    ; Store PSP Address
  825.             mov     MCBS[bp].mcba,es    ; MCB Address and
  826.             mov     MCBS[bp].mcbl,bx    ; Length to Next MCB
  827. CkBlock:    cmp     BYTE PTR es:[0],"Z" ; If Last MCB
  828.             je      LastMCB             ; then MCBs done
  829.             cmp     BYTE PTR es:[0],"M" ; else if Next MCB
  830.             je      NextMCB             ; then process MCB
  831.             mov     es,sbuffer          ; else Restore Buffer
  832.             stc                         ; Segment and Exit
  833.             jmp     ExitMCB             ; with CY flag set
  834. NextMCB:    mov     dx,es               ; If MCB address
  835.             add     bx,dx               ; plus length to
  836.             inc     bx                  ; next from PSP is before
  837.             cmp     bx,spsp             ; segment of current PSP
  838.             jc      MCBLoop             ; then loop until there
  839. LastMCB:    mov     es,sbuffer          ; else Restore Buffer Segment
  840.             xor     bx,bx               ; Initialize MCB Index Pointer
  841.             call    SortMCBs            ; Sort by PSP and space buffer
  842. StoLoop:    add     bx,6                ; Advance MCB Index
  843.             mov     startl,di           ; UpDate Start of Line
  844.             inc     di                  ; Start with a space
  845.             mov     ax,MCBS[bx].pspa    ; Get PSP Address Word
  846.             push    ax                  ; Preserve LSB while
  847.             mov     al,ah               ; isolate MSB and
  848.             call    Val2ASCh            ; store 1st MSB and
  849.             stosb                       ; 2nd HEX ASCII digits
  850.             pop     ax                  ; Restore LSB and
  851.             push    ax                  ; Preserve for decision
  852.             call    Val2ASCh            ; Store 1st LSB and
  853.             stosb                       ; 2nd HEX ASCII digits
  854.             inc     di                  ; plus a space
  855.             mov     ax,MCBS[bx].mcba    ; Get MCB Address Word
  856.             push    ax                  ; Preserve LSB while
  857.             mov     al,ah               ; isolate MSB and
  858.             call    Val2ASCh            ; store 1st MSB and
  859.             stosb                       ; 2nd HEX ASCII digits
  860.             pop     ax                  ; Restore LSB and
  861.             call    Val2ASCh            ; store 1st LSB and
  862.             stosb                       ; 2nd HEX ASCII digits
  863.             pop     ax                  ; If PSP
  864.             cmp     ax,MCBS.pspa        ; Was Last
  865.             jnc     WasLast             ; then End
  866.             push    cx                  ; else Preserve StoLoop
  867.             push    bx                  ; counter and MCBS Index
  868.             mov     bx,MCBS[bx].mcba    ; If the MCB
  869.             inc     bx                  ; plus one
  870.             cmp     ax,bx               ; equals PSP
  871.             jz      FCounts             ; then count
  872.             add     di,4                ; else advance pointer
  873.             jmp     SHORT NoFileX
  874. FCounts:    mov     bp,di               ; Preserve MapData Pointer
  875.             mov     es,ax               ; Point to Segment and
  876.             mov     di,18h              ; Offset of DOS Files
  877.             mov     cx,20               ; Initialize Counter
  878.             mov     al,0FFh             ; Looking for closed
  879.             repne   scasb               ; Preserve position
  880.             mov     ax,di               ; after search
  881.             mov     es,sbuffer          ; Restore Data Buffer
  882.             mov     di,bp               ; Segment and Pointer
  883.             sub     ax,19h              ; Calculate open files
  884.             xor     dx,dx               ; as a double word
  885.             mov     bx,4                ; Set number of places
  886.             push    ax                  ; Arg 1 - LSW
  887.             push    dx                  ; Arg 2 - MSW
  888.             push    di                  ; Arg 3 - dest
  889.             push    bx                  ; Arg 4 - places
  890.             call    BinToDStr           ; Store number of files
  891. NoFileX:    pop     bx                  ; Restore Index and
  892.             pop     cx                  ; StoLoop Counter
  893.             inc     di                  ; Advance to end of files
  894.             mov     ax,MCBS[bx].mcbl    ; Store length as
  895.             jmp     SHORT P2Bytes       ; decimal bytes
  896. WasLast:    neg     ax                  ; Calculate
  897.             add     ax,tmem             ; free memory
  898.             mov     si,OFFSET freem+1   ; Store " free"
  899.             mov     cx,5                ; memory bytes
  900.             rep     movsb               ; Counter now 0
  901. P2Bytes:    push    cx                  ; Preserve Counter
  902.             push    bx                  ; and MCB Index
  903.             xor     dx,dx               ; Clear top and
  904.             mov     bx,10h              ; multiply into
  905.             mul     bx                  ; double word bytes
  906.             mov     bx,7                ; Set for 7 place
  907.             push    ax                  ; integerLSW and
  908.             push    dx                  ; integerMSW to
  909.             push    di                  ; store into
  910.             push    bx                  ; the data
  911.             call    BinToDStr
  912.             pop     bx                  ; Restore Index and
  913.             pop     cx                  ; If Counter is zero
  914.             jcxz    WorkEnd             ; then work is done
  915.             call    OwnComVec           ; else finish line
  916.             jmp     StoLoop             ; Until Last PSP
  917. WorkEnd:    mov     ax,0A0Dh            ; End the
  918.             stosw                       ; Last Line
  919. ExitMCB:    ret
  920. WorkMCBs    ENDP
  921.  
  922. DoIMdata    PROC
  923.             push    ds                  ; Preserve Data Segment
  924.             push    ax                  ; and Pointer to DOS Data
  925.             mov     si,ax               ; Initialize Source Index
  926.             mov     cx,8                ; Pointer and Counter
  927.             mov     ax,40h              ; Set DOS data segment in
  928.             mov     ds,ax               ; Data Segment Register
  929.             cmp     si,0A8h             ; If EGA Info Area
  930.             jz      IMAOk               ; then bytes IS 8
  931.             add     cx,8                ; else bytes is 16
  932. IMAOk:      push    cx                  ; Preserve byte counter
  933. IMdigL:     inc     di                  ; Space before
  934.             lodsb                       ; data byte's
  935.             call    Val2ASCh            ; first and
  936.             stosb                       ; 2nd HEX ASCII digits
  937.             loop    IMdigL              ; until count complete
  938.             pop     cx                  ; Restore byte counter
  939.             pop     si                  ; and DOS data pointer
  940.             add     di,2                ; Add 2 spaces
  941.             cmp     si,0A8h             ; If NOT 8 byte EGA
  942.             jnz     IMascL              ; then ready for ASCII
  943.             add     di,8                ; else need 8 spaces
  944. IMascL:     lodsb                       ; Get a byte
  945.             cmp     al,20h              ; If => space
  946.             jnc     CkHigh              ; then check delete
  947. UseDot:     mov     al,"."              ; else use a dot
  948. CkHigh:     cmp     al,7Fh              ; If => delete
  949.             jnc     UseDot              ; then use a dot
  950.             stosb                       ; Send to MapData
  951.             loop    IMascL              ; until CX 'em
  952.             pop     ds                  ; Restore Data Segment
  953.             mov     ax,0A0Dh            ; End the line
  954.             stosw
  955.             ret
  956. DoIMdata    ENDP
  957. InfoMap     PROC
  958.             call    Underline           ; Underline block data
  959.             mov     si,OFFSET EgaHdg    ; Transfer EGA Info
  960.             mov     cx,EgaLen           ; Area Heading
  961.             rep     movsb
  962.             mov     ax,0A8h             ; Point to and
  963.             call    DoIMdata            ; transfer EGA data
  964.             mov     si,OFFSET IcaHdg    ; Transfer Inter-
  965.             mov     cx,IcaLen           ; Application Area
  966.             rep     movsb               ; Heading bytes
  967.             mov     ax,0F0h             ; Point to and
  968.             call    DoIMdata            ; get ICA data
  969. Underline:  mov     ax,"- "
  970.             stosb                       ; Space plus
  971.             mov     al,ah               ; Minus sign
  972.             mov     cx,76               ; Underlines
  973.             rep     stosb
  974.             mov     ax,0A0Dh            ; End the
  975.             stosw                       ; underline
  976.             ret
  977. InfoMap     ENDP
  978.  
  979. EmmsMap     PROC
  980.             mov     ax,3567h            ; Get Vector for
  981.             int     21h                 ; Function 67hex
  982.             push    di                  ; Preserve store pointer
  983.             mov     di,000Ah            ; If Device
  984.             mov     cx,8                ; Name is NOT
  985.             rep     cmpsb               ; "EMMXXXX0"
  986.             mov     es,sbuffer          ; after restore
  987.             pop     di                  ; storage ES:DI
  988.             jne     EmsErrX             ; then Error Exit
  989.             mov     ah,46h              ; or if version
  990.             int     67h                 ; number request
  991.             or      ah,ah               ; returns error
  992.             jnz     EmsErrX             ; then Error Exit
  993.             mov     si,OFFSET emmshdg   ; else store 1st
  994.             mov     cx,emmlen1          ; heading line
  995.             rep     movsb               ; with Version
  996.             call    Val2ASCh            ; Major Number
  997.             mov     ah,"."              ; plus dot and
  998.             xchg    al,ah               ; Minor Number
  999.             stosw
  1000.  
  1001.             mov     cx,emmlen2          ; Add 2nd heading
  1002.             rep     movsb               ; line lead-in to
  1003.             mov     ah,41h              ; EMS Page Frame
  1004.             int     67h                 ; If Page Frame
  1005.             or      ah,ah               ; Request Fails
  1006.             jnz     EmsErrX             ; then Error Exit
  1007.             mov     al,bh               ; else store HEX
  1008.             call    Val2ASCh            ; digits one and
  1009.             stosb                       ; two and follow
  1010.             mov     al,bl               ; with the third
  1011.             call    Val2ASCh            ; and fourth plus
  1012.             mov     ah,")"              ; ending parenthesis
  1013.             stosw
  1014.             mov     ax,0A0Dh            ; End the line
  1015.             stosw
  1016.             mov     ah,4Bh              ; Get Handle
  1017.             int     67h                 ; Count in BX
  1018.             or      ah,ah               ; If Response
  1019.             jz      EmPages             ; then Map Pages
  1020. EmsErrX:    mov     si,OFFSET emserm    ; else store
  1021.             mov     cx,emerml           ; E M S
  1022.             rep     movsb               ; Error
  1023.             jmp     SHORT EmmExit       ; Message
  1024. EmPages:    mov     cx,bx               ; Set Handle Counter
  1025.             inc     cx                  ; for zero thru [bx]
  1026.             xor     dx,dx               ; Count up from 0
  1027. HndLoop:    mov     ah,4Ch              ; Get Assigned
  1028.             int     67h                 ; Handle Pages
  1029.             or      ah,ah               ; If Error
  1030.             jnz     NoPages             ; then skip
  1031.             or      bx,bx               ; else if > 0
  1032.             jnz     PagesOk             ; then store
  1033. NoPages:    inc     dx                  ; else loop until
  1034.             loop    HndLoop             ; CX handles done
  1035.             jmp     SHORT HndExit
  1036. PagesOk:    push    dx                  ; Preserve Handle
  1037.             push    cx                  ; Handle Counter
  1038.             push    bx                  ; and Handle Pages
  1039.             mov     cx,6                ; Set places
  1040.             xor     ax,ax               ; and MSW
  1041.             push    dx                  ; Arg 1 - LSW
  1042.             push    ax                  ; Arg 2 - MSW
  1043.             push    di                  ; Arg 3 - destination
  1044.             push    cx                  ; Arg 4 - places
  1045.             call    BinToDStr           ; Store Handle Number
  1046.             pop     ax                  ; Restore Pages and
  1047.             add     tpages,ax           ; accumulate total
  1048.             call    PgsAndKbs           ; Store Pages and KiloBytes
  1049.             pop     cx                  ; Restore Counter
  1050.             pop     dx                  ; and EMS Handle
  1051.             add     di,3                ; else Advance to
  1052.             mov     ax,5300h            ; UserName Start to be
  1053.             int     67h                 ; Stored If Available
  1054.             add     di,8                ; Advance Past Area
  1055. HndlEnd:    mov     ax,0A0Dh            ; End the line
  1056.             stosw
  1057.             inc     dx                  ; Increment Handle
  1058.             loop    HndLoop             ; until CX'em done
  1059. HndExit:    mov     ah,42h              ; Get Free
  1060.             int     67h                 ; Pages
  1061.             mov     dx,tpages           ; Calculate
  1062.             add     dx,bx               ; Total Pages
  1063.             mov     si,OFFSET freem     ; Store
  1064.             mov     cx,6                ; "  free"
  1065.             rep     movsb               ; lead-in
  1066.             push    dx                  ; Preserve Total
  1067.             mov     ax,bx               ; Store Free as
  1068.             call    PgsAndKbs           ; Pages and KiloBytes
  1069.             mov     si,OFFSET dashes+24 ; Space Over
  1070.             mov     cx,11               ; and dash-out
  1071.             rep     movsb               ; UserName
  1072.             mov     ax,0A0Dh            ; End the line
  1073.             stosw
  1074.             mov     si,OFFSET totlm     ; Store
  1075.             mov     cx,6                ; " total"
  1076.             rep     movsb               ; lead-in
  1077.             pop     ax                  ; Store Total as
  1078.             call    PgsAndKbs           ; Pages and KiloBytes
  1079.             mov     si,OFFSET dashes+24 ; Space Over
  1080.             mov     cx,11               ; and dash-out
  1081.             rep     movsb               ; UserName
  1082. EmmExit:    mov     ax,0A0Dh            ; End the line
  1083.             stosw
  1084.             ret
  1085. EmmsMap     ENDP
  1086.  
  1087. Vectors     PROC
  1088.             mov     si,OFFSET WatchS    ; else if last
  1089.             push    di                  ; command line
  1090.             sub     di,19               ; parameter was
  1091.             mov     cx,11               ; "TSR WATCHER"
  1092.             rep     cmpsb               ; then WATCH is
  1093.             pop     di                  ; installed
  1094.             jnz     CkWatch             ; else check flag
  1095.             mov     WatchF,ax           ; Set Watch PSP as Flag
  1096. CkWatch:    cmp     WatchF,0            ; If NO TSR WATCHER Installed
  1097.             jz      UseHook             ; then Hooked else Chained Vectors
  1098.             push    ds                  ; Preserve Data Segment
  1099.             mov     ds,WatchF           ; while Point to Watch
  1100.             mov     dx,ax               ; Copy Program PSP
  1101.             mov     si,104h             ; Get Next Vector
  1102.             lodsw                       ; Position in
  1103.             mov     si,220h             ; Vector Change
  1104.             add     ax,si               ; Storage Area
  1105.             mov     vpos,ax             ; Store for Comparison
  1106.             mov     ax,dx               ; Restore PSP and Zero
  1107.             xor     bp,bp               ; Vector/Line Counter
  1108. FFLoop:     cmp     si,vpos             ; If at Table End
  1109.             jz      WatchX              ; then exit done
  1110.             lodsw                       ; else if Word
  1111.             cmp     ax,-1               ; is NOT pspid
  1112.             jne     FFLoop              ; then keep looking
  1113.             lodsw                       ; or if Program PSP
  1114.             cmp     ax,dx               ; is NOT in next word
  1115.             jne     FFLoop              ; then keep looking
  1116.             add     si,4                ; else Point to Vectors
  1117. WatchL:     lodsw                       ; If Next pspid
  1118.             cmp     ax,-1               ; is found
  1119.             jz      WatchX              ; then exit done
  1120.             cmp     ah,0                ; else if Case ID = 0
  1121.             jz      WatchO              ; then check columns Ok
  1122.             cmp     bp,0                ; else if Vectors Written
  1123.             jnz     WatchX              ; then exit done
  1124.             pop     ds                  ; else Restore DS
  1125.             mov     si,OFFSET disam     ;  and store "***
  1126.             mov     cx,disalen          ; D I S A B L E D
  1127.             rep     movsb               ; ***" and exit
  1128.             jmp     SHORT INTExit
  1129. WatchO:     cmp     bp,9                ; If NOT to last column
  1130.             jc      WatchW              ; then store Vector
  1131.             mov     WORD PTR es:[di],0A0Dh
  1132.             add     di,53               ; else start new line
  1133.             xor     bp,bp               ;  and update counter
  1134. WatchW:     call    Val2ASCh            ; Store 2 HEX ASCII
  1135.             mov     ah," "              ; digits plus a space
  1136.             stosw
  1137.             inc     bp                  ; Count Vector
  1138.             add     si,6                ; Advance to next
  1139.             jmp     SHORT WatchL        ; vector until exit
  1140. WatchX:     pop     ds                  ; Restore Data Segment
  1141.             jmp     SHORT INTExit
  1142. UseHook:    mov     bp,di               ; else copy Pointer
  1143.             xor     di,di               ; Point ES:DI to
  1144.             mov     es,di               ; DOS INT Vectors
  1145.             mov     cx,512              ; Set Word Count
  1146.             mov     dx,4                ; and INT Divisor
  1147. INTLoop:    mov     ax,MCBS[bx].pspa    ; Scan for PSP in
  1148.             repne   scasw               ; DOS Vector Table
  1149.             mov     es,sbuffer          ; Restore ES:DI to Buffer
  1150.             xchg    bp,di               ; If at End of Vector Table
  1151.             jcxz    INTExit             ; then Vectors are Done
  1152.             mov     ax,bp               ; else Calculate
  1153.             div     dl                  ; Vector Number
  1154.             dec     ax                  ; Zero - Based
  1155.             call    Val2ASCh            ; Display 2 HEX ASCII
  1156.             mov     ah," "              ; digits plus a space
  1157.             stosw
  1158.             xor     ax,ax               ; Reset Extra Segment
  1159.             mov     es,ax               ; and Pointer to Vectors
  1160.             xchg    bp,di               ; preserving MapData Pointer
  1161.             mov     ax,startl           ; If start of current row
  1162.             add     ax,columns-3        ; to position after end
  1163.             cmp     bp,ax               ; is greater than pointer
  1164.             jc      INTLoop             ; then loop until end/done
  1165.             mov     WORD PTR es:[bp],0A0Dh
  1166.             add     bp,2                ; else start new line
  1167.             mov     startl,bp           ; mark start of line
  1168.             add     bp,51               ; Advance to Vector Area
  1169.             jmp     SHORT INTLoop       ; Loop Until Vectors Done
  1170. INTExit:    ret
  1171. Vectors     ENDP
  1172.             END     Main
  1173.