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