home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / SYSUTL / TSRWRK32.ZIP / SHOWTSRS.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-06-06  |  38.8 KB  |  1,374 lines

  1.     Title    SHOWTSRS - Program to scroll MAPMEM data
  2. Comment ~                31-May-1989 00:03:10
  3.     Author:     Tom Gilbert's Heart&Mind
  4.             7127 Lafayette Avenue
  5.             Kansas City, KS 66109
  6.             (913) 299-2701
  7.  
  8.     Copyright   (c) 1988/9 by Heart & Mind
  9.             for NON-Commercial Use ONLY
  10.             Use and distribution in the
  11.             Public Domain is encouraged
  12. v3.2 Toad hall Tweak
  13.     ~
  14.     DOSSEG
  15.     .MODEL  small
  16.     .STACK  100h
  17.     .DATA
  18. headline    label    byte
  19.     DB    " >ShowTSRs [anything for HELP]  -  Version 3.2  - "
  20.     DB    " by Tom Gilbert's Heart&Mind",13,10," ",13,10
  21.  
  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 13,10,"        "
  28. DB "ShowTSRs displays a map of memory blocks and interrupts used"
  29. DB 13,10,"        "
  30. DB "     by TurboPower DISABLE and RELEASE or UnMark and ReMark."
  31. DB 13,10,13,10,"    "
  32. DB 'The "PSP" is the Segment of a program, environment or "trapped"'
  33. DB 13,10,"                       memory block."
  34. DB 13,10,13,10,"    "
  35. DB 'The "MCB" (Memory Control Block) is located one paragraph before'
  36. DB 13,10,"                   the block it controls."
  37. DB 13,10,13,10,"    "
  38. DB 'The "files" include the 5 standard DOS devices.'
  39. DB 13,10,13,10,"    "
  40. DB 'The "bytes" are block lengths in decimal.'
  41. DB 13,10,13,10,"    "
  42. DB 'The "owner" names other than "DOS", "TSR WATCHER", "LoadTSR" and'
  43. DB 13,10,"        "
  44. DB 'those for [F]Marks come from the environment.  The name "command"'
  45. DB 13,10,"        "
  46. DB 'appears when NO "owner" is found in the environment.'
  47. DB 13,10,13,10,"    "
  48. DB 'The "command line" is reproduced for the first 16 bytes.'
  49. DB 13,10,"        "
  50. DB "Those followed by an elipsis (...) exceed 16 bytes."
  51. DB 13,10,13,10,"    "
  52. DB 'The "vectors" which are "chained" from program to program will be'
  53. DB 13,10,"        "
  54. DB "displayed if WATCH is installed.  Otherwise, only those at the top"
  55. DB 13,10,'        of the chain ("hooked") are displayed.'
  56. DB 13,10,13,10,"    "
  57. DB "EGA Info 8 bytes and Inter-application Communication"
  58. DB 13,10,"        "
  59. DB "Area 16 bytes are provided in HEX & ASCII dump format."
  60. DB 13,10,13,10,"    "
  61. DB "If expanded memory is installed, the Manager's Version number,"
  62. DB 13,10,"        "
  63. DB "Page Frame Segment (through which memory is windowed) and block"
  64. DB 13,10,"        "
  65. DB "information will be shown.  User names are shown if provided."
  66. DB 13,10,13,10,"  "
  67. DB "                     ***** End of ShowTSRs Help *****",13,10
  68. HELPLEN equ $-helpdat
  69. statline DB    " Line:    of    "
  70.     DB    " Move:   PGUP PGDN HOME END or Use ESC key to"
  71.     DB    " Exit: ShowTSRs "
  72. cmdparam DB    " ",13
  73. datf    DB    0        ; Command flag 0 = Data else HELP
  74. spsp    DW    ?        ; Segment of ProgramSegmentPrefix
  75. fmem    DW    ?        ; Free System Conventional RAM
  76. pbuffer    DW    0        ; Position in buffer (offset)
  77. sbuffer    DW    ?        ; Base of buffer (segment)
  78. lbuffer    DW    ?        ; Length of buffer
  79. linenum    DW    ?        ; Data buffer line
  80. lastnum    DW    ?        ; Last buffer line
  81. COLUMNS    EQU    80        ; Number of columns used per row
  82. rows    DW    24        ; Number of last row for display
  83. datrows    DW    20        ; Number of data rows per page
  84. lastrow    DW    24        ; Number of last display row
  85. cell    LABEL    WORD        ; Cell (character and attribute)
  86. char    DB    " "        ; Initialize to space
  87. attr    DB    ?        ; Attribute
  88. mode    DB    ?        ; Initial mode
  89. pag    DB    ?        ; Initial display page
  90. newvid    DB    0        ; Video change flag
  91. cga    DB    1        ; CGA flag - default yes
  92. vidadr    DW    0B800h        ; Video buffer address - default CGA
  93. MONO    EQU    0B000h        ; Monochrome address
  94. statatr    DB    030h        ; Color default - black on cyan
  95. BWSTAT    EQU    070h        ; B&W default - black on white
  96. scrnatr    DB    017h        ; Color default - white on blue
  97. BWSCRN    EQU    007h        ; B&W default - white on black
  98.  
  99. exkeys    DB 71,72,73,79,80,81; Extended key codes
  100. LEXKEYS    EQU     $-exkeys    ; Table of keys
  101. extable    DW  HomeK,upk,pgupk,endk,downk,PgDnK,NoneK
  102.  
  103. egahdg    DB " EGA Information Area at 0040:00A8 "
  104. EGALEN    EQU $-egahdg
  105. icahdg    DB " Inter-application Communications Area:",13,10," 0040:00F0 "
  106. ICALEN    EQU $-icahdg
  107. emsname    DB "EMMXXXX0"        ; EMM standard Name
  108. tpages    DW 0            ; Page accumulator
  109. emserm    DB 13,10
  110.     DB "   *** Expanded Memory NOT Installed or NOT Working ***"
  111. EMERML    EQU $-emserm
  112. emmshdg    DB " block    pages   KBytes   UserName  "
  113.     DB "  (Expanded Memory - Version "
  114. EMMLEN1    EQU $-emmshdg
  115.     DB ")",13,10
  116. dashes    DB " -----    -----   ------   --------   "
  117.     DB " (LIM page frame address - "
  118. EMMLEN2    EQU $-emmshdg-EMMLEN1
  119. totlm    DB " total"
  120. freem    DB "  free"
  121. fmark    DB "FMark TSR"        ; [F]Mark ID - Now using " TSR"
  122.  
  123. doscm    DB "DOS<command.com><CONFIG.SYS> <environment><trapped>"
  124. disam    DB "***  D I S A B L E D  ***"
  125. DISALEN    EQU $-disam
  126. loadtsr    DB "Load"        ; LoadTSR Command Identification
  127. watchS    DB "TSR WATCHER"    ; WATCH Command Line Parameter
  128. watchF    DW  0            ; MCB Index to WATCH PSP if Set
  129. startl    DW  0            ; Destination Index at Line Start
  130. vpos    DW  ?            ; WATCH Next PSP Position
  131.  
  132. MCB    STRUC
  133. pspa    DW  0            ; Program Segment Prefix or Mark Address
  134. mcba    DW  0            ; Memory Allocation Block Address
  135. mcbl    DW  0            ; Length in paragraphs to next MCB
  136. mcbf    DW  0            ; Flags 0=Trapped, FF=Env, FF00=PGM
  137. MCB    ENDS            ;   and Special Blocks are FFFF
  138.  
  139. mcbs    MCB   100 DUP (<>)    ; Array of MCB Structures
  140.  
  141.     .CODE
  142.  
  143. Main    PROC
  144.     mov    ax,@data    ; Destination is data
  145.     mov    ES,ax        ; flag with length of
  146.     mov    di,OFFSET datf    ; command line
  147.     mov    si,80h        ; parameter
  148.     movsb
  149.     mov    ES:spsp,DS    ; Preserve PSP Segment and
  150.     mov    bx,DS:[2]    ; Use Total System RAM to
  151.     sub    bx,ES:spsp    ; Calculate Free Memory
  152.     mov    DS,ax        ; Set DS Register to DATA
  153.     mov    fmem,bx        ; Store Free Memory
  154.  
  155.     cli            ; Turn off interrupts
  156.     mov    SS,ax        ; Make SS and
  157.     mov    sp,OFFSET STACK    ;   SP relative to DGROUP
  158.     sti            ; Re-Enable interrupts
  159.  
  160.     mov    bx,sp        ; Convert stack pointer to
  161.     mov    cl,4        ; number of stack paragraphs
  162.     shr    bx,cl
  163.     add    ax,bx        ; Add SS to get end of program
  164.     sub    ax,spsp        ; Subtract start to get length
  165.     mov    ES,spsp        ; Modify Memory
  166.     mov    bx,ax        ; New Block Size
  167.     mov    ah,4Ah        ; through DGROUP
  168.     int    21h
  169.     mov    bx,0FFFFh
  170. GetMore:
  171.     mov    ah,48h        ; Request all
  172.     int    21h        ; remaining
  173.     jc    GetMore        ; memory
  174.  
  175.     mov    ES,ax        ; Set Es Register to Block
  176.     mov    sbuffer,ax    ; Save buffer segment and
  177.     mov    lbuffer,bx    ; actual length allocated
  178.     xor    di,di        ; Point to beginning and
  179. ;v1.1    mov    cx,lbuffer    ; fill data buffer
  180.     mov    cx,bx    ;lbuffer    ;fill data buffer        v1.1
  181.     mov    al," "        ; With Spaces
  182.     rep    stosb
  183.     xor    di,di
  184.     test    datf,0FFh    ; If command parameter
  185.     jnz    HelpOpt        ; then provide HELP
  186.      xor    dx,dx        ; else zero index
  187.      call    GetData        ; Get and Show
  188.      jmp    SHORT EndData    ; scrollable data
  189.  
  190. HelpOpt:
  191.     mov    cmdparam,"?"        ; Show HELP requested
  192.     mov    si,OFFSET helpdat    ; and store help data
  193.     mov    cx,HELPLEN        ; for scrollable display
  194.     rep    movsb
  195. EndData:
  196.     call    EndCount        ; Count buffer
  197.     mov    ax,linenum        ; data lines and
  198.     mov    lastnum,ax        ; store the count
  199.     mov    lbuffer,di        ; and store length
  200.     call    Video            ; Adjust for mode & adapter
  201.     mov    dx,2B00h        ; Hide cursor off screen
  202.     xor    bh,bh
  203.     mov    ah,2
  204.     int    10h
  205.     call    HomeK            ; Display 1st Page
  206.     mov    ax,datrows        ; If more data
  207.     sub    ax,lastnum        ; lines to show
  208.     jc    NextKey            ; then accept keys
  209.      sub    datrows,ax        ; else modify last
  210.      sub    lastrow,ax        ; row for ending
  211. NextKey:
  212.     mov    ah,7            ; Get a key
  213.     int    21h
  214.     or    al,al            ; If a null            v1.1
  215.     je    Extended        ; then Must be extended code
  216.     cmp    al,27            ; else If NOT ESCape
  217.     jne    NextKey            ; then Ignore unknown command
  218.  
  219. quit:    mov    ES,sbuffer        ; Release buffer
  220.     mov    ah,49h
  221.     int    21h
  222.     cmp    newvid,1        ; If video not changed
  223.     jne    thatsall        ; then that's all
  224.     mov    al,mode            ; else Restore video mode,
  225.     xor    ah,ah
  226.     int    10h
  227.     mov    al,pag            ; page,
  228.     mov    ah,5
  229.     int    10h            ; and cursor
  230. thatsall:
  231.     mov    cx,lastrow        ; Load last row and
  232.     mov    ax,rows            ; Calculate rows to
  233.     sub    ax,cx            ; be scrolled blank
  234.     xchg    cl,ch            ; Set Upper Left and
  235.     mov    dx,cx            ; copy in order to
  236.     add    dh,al            ; adjust Lower Right
  237.     mov    dl,COLUMNS-1        ; corner of window
  238.     mov    ah,6            ; Call ROM BIOS to
  239.     mov    bh,7            ; clear the window
  240.     int    10h
  241.     mov    dx,cx            ; Set cursor above
  242.     dec    dh            ; window so prompt
  243.     xor    bh,bh            ; is on last line
  244.     mov    ah,2            ; when Exit to DOS
  245.     int    10h
  246.     mov    ax,4C00h        ; Zero Error Level
  247.     int    21h            ; For => DOS 2.00
  248.                     ; RED SWITCH for 1
  249.  
  250. Extended:
  251.     mov    ah,7            ; Get extended code
  252.     int    21h
  253.     push    ES
  254.     push    DS            ; Load DS into ES
  255.     pop    ES
  256.     mov    di,OFFSET exkeys    ; Load address and
  257.     mov    cx,LEXKEYS+1        ; length of key list
  258.     repne   scasb            ; Find position
  259.     pop    ES
  260.     sub    di,(OFFSET exkeys)+1    ; Point to key and adjust
  261.     shl    di,1            ; pointer for word addresses
  262.     call    extable[di]        ; Call appropriate procedure
  263.     jmp    NextKey
  264.  
  265. HomeK:
  266. ;v1.1    mov    pbuffer,0        ; HOME - Zero the buffer
  267. ;v1.1    mov    ax,pbuffer        ; position for 1st page
  268.     xor    ax,ax            ;HOME - zero the buffer        v1.1
  269.     xchg    ax,pbuffer        ;pbuffer cleared, AX=old val    v1.1
  270.     jmp    SHORT GoPage
  271.  
  272. upk:    mov    ax,-1            ; UP - GoBack one line if room
  273.     jmp    SHORT GoPage
  274.  
  275. pgupk:    mov    ax,datrows        ; PGUP - Page back
  276.     neg    ax            ; Up to page lines
  277.     jmp    SHORT GoPage
  278.  
  279. endk:    mov    ax,lbuffer        ; END - Get last byte of file
  280.     mov    pbuffer,ax        ; Make it the file position
  281.     mov    ax,datrows        ; Go Backward enough
  282.     neg    ax            ; lines for last page
  283.     jmp    SHORT GoPage
  284.  
  285. downk:    mov    ax,1            ; GoForward 1 line if room
  286.     jmp    SHORT GoPage
  287.  
  288. PgDnK:    mov    ax,datrows        ; PGDN - Go forward <= page
  289. GoPage:    push    ax
  290.     call    Pager
  291. NoneK:    retn                ; Ignore unknown key
  292. Main        ENDP
  293.  
  294. Video        PROC
  295.     push    ES            ; Preserve Extra Segment
  296.     mov    ah,12h            ; Call EGA status function
  297.     mov    bl,10h
  298.     sub    cx,cx            ; With Clear status bits
  299.     int    10h
  300.     sub    ax,ax            ; If status is still Clear
  301.     jcxz    modechk
  302.  
  303.     mov    ES,ax            ; or if EGA is NOT active
  304.     test    BYTE PTR ES:[487h],1000b
  305.     jnz    modechk            ; then check CGA or Mono Mode
  306.  
  307.     mov    ax,1130h        ; else get EGA information
  308.     int    10h
  309.     mov    al,dl            ; Make lines per screen
  310.     cbw                ; into a Word Value
  311.     mov    rows,ax            ; Reset number of the
  312.     mov    lastrow,ax        ; last row and number
  313.     sub    ax,4            ; of rows available for
  314.     mov    datrows,ax        ; data from their defaults
  315.     dec    cga            ; Clear the CGA Flag
  316. modechk:
  317.     pop    ES            ; Restore Extra Segment
  318.     mov    ah,0Fh            ; Get video mode
  319.     int    10h
  320.     mov    mode,al            ; Save initial
  321.     mov    pag,bh            ; mode and page
  322.     mov    dl,al            ; Work on copy
  323.     cmp    dl,7            ; If mono 7
  324.     je    loadmono        ; then Set mono
  325.      cmp    dl,15            ; else if NOT mono 15
  326.      jne    graphchk        ; then Check graphics
  327. loadmono:
  328.     mov    vidadr,MONO        ; else Load mono address
  329.     mov    statatr,BWSTAT        ; Set B&W defaults for status
  330.     mov    scrnatr,BWSCRN        ; line and screen background
  331.     dec    cga            ; Set as NOT CGA
  332.     cmp    al,15            ; If NOT mono 15
  333.     jne    VidExit            ; then Done
  334.     mov    dl,7            ; else Set standard mono
  335.     jmp    SHORT chmode
  336.  
  337. graphchk:
  338.     cmp    dl,7            ; If 7 or higher
  339.     jg    color            ; then color or done
  340.     cmp    dl,4            ; else 5 and 6 are
  341.     jg    bnw            ; usually black and white
  342.     je    color            ; 4 is color
  343.     test    dl,1            ; AND
  344.     jz    bnw            ; 0 and 2 are black and white
  345. color:    cmp    dl,3            ; If mode 3
  346.     je    VidExit            ; then Done
  347.      mov    dl,3            ; else use color text mode
  348.      jmp    SHORT chmode
  349.  
  350. bnw:    mov    statatr,BWSTAT        ; Set B&W defaults for status
  351.     mov    scrnatr,BWSCRN        ; line and screen background
  352.     cmp    dl,2            ; If mode 2
  353.     je    VidExit            ; then Done
  354.      mov    dl,2            ; else use B&W text mode
  355. chmode:    mov    al,dl            ; Set video mode
  356.     xor    ah,ah
  357.     int    10h
  358.     mov    ax,0500h        ; Set video page 0
  359.     int    10h
  360.     mov    newvid,1        ; Set flag
  361. VidExit:
  362.     ret
  363. Video        ENDP
  364.  
  365. ; Procedure EndCount - Go backward to count lines in file
  366. ; Input    ES:DI has buffer position
  367. ; Output    Modifies "linenum"
  368.  
  369. EndCount    PROC
  370.     push    di
  371.     std                ; Go backwards to
  372.     mov    al,13            ; Search for CR
  373.     mov    linenum,0        ; Initialize line count
  374. findstrt:
  375.     mov    cx,0FFh            ; Load maximum character count
  376.     cmp    cx,di            ; If NOT Near start of buffer
  377.     jl    notnear2        ; then use maximum count
  378.      mov    cx,di            ; else search
  379.      jcxz    found            ; only to start
  380.  
  381. notnear2:
  382.     repne   scasb            ; If previous CR NOT found
  383.     jcxz    found            ; then must be at start
  384.      inc    linenum            ; else adjust line count
  385.      jmp    SHORT findstrt        ;  and continue search
  386.  
  387. found:    pop    di            ; Restore index
  388.     cld                ; and direction
  389.     ret
  390. EndCount    ENDP
  391.  
  392. ; Procedure Pager - Displays status and text lines
  393. ; Input    Stack variable: lines to scroll (negative up, positive down)
  394. ; Output    Displays status plus "datrows" number of data lines
  395.  
  396. Pager        PROC
  397.     push    bp
  398.     mov    bp,sp
  399.     mov    di,pbuffer        ; Index to buffer position
  400.     mov    cx,[bp+4]        ; Get count argument for
  401.     mov    ax,10            ; linefeeds to count and
  402.     or    cx,cx            ; If No lines to count
  403.     jz    show            ; then show the page
  404.     jg    forward            ; else Count Forward
  405.      call    GoBack            ; or Backward if neg
  406.      jmp    SHORT show        ; before showing page
  407.  
  408. forward:
  409.     call    GoForwd
  410. show:    call    EndCount        ; Count to first
  411.     mov    ax,linenum        ; line number to show
  412.     add    ax,datrows        ; Adjust to bottom line
  413.     cmp    ax,lastnum        ; If NOT past last
  414.     jle    lineok            ; then number is ok
  415.      mov    ax,lastnum        ; else make it last
  416.  
  417. lineok:    push    DS            ; Set Status Line DATA as
  418.     pop    ES            ; Destination for Values
  419.     mov    di,OFFSET statline[9]
  420.     xor    dx,dx            ; Make 32-bit
  421.     call    BinToDStr        ; Line Number
  422.     mov    ax,lastnum        ;  and Last
  423.     add    di,6            ; Line Number
  424.     call    BinToDStr        ; Restore
  425.     mov    ES,sbuffer        ; ES to sbuffer
  426.  
  427.     mov    bl,statatr        ; Set attribute for
  428.     mov    BYTE PTR cell[1],bl    ; status & headings
  429.     xor    bx,bx            ; Initialize counter
  430.     mov    si,OFFSET headline    ; for heading lines
  431. hdloop:    push    bx            ; Preserve counter
  432.     push    DS            ; Arg 1 - Segment
  433.     push    si            ; Arg 2 - Offset
  434.     push    bx            ; Arg 3 - Display Line
  435.     push    cell            ; Arg 4 - Char/Attrib
  436.     call    CellWrt            ; Write one line
  437.     push    SS            ; Restore DGroup
  438.     pop    DS            ; into DS register
  439.     pop    bx            ; Restore line count and
  440.     mov    si,ax            ; get returned position
  441.     inc    bx            ; Count the heading line
  442.     cmp    bx,4            ; If NOT yet 4 lines
  443.     jc    hdloop            ; then loop until 4
  444.  
  445.     mov    al,scrnatr        ; Change attribute for
  446.     mov    BYTE PTR cell[1],al    ; data buffer display
  447.     mov    si,pbuffer        ; Index to pbuffer
  448. datloop:
  449.     push    bx            ; Preserve counter
  450.     push    sbuffer            ; Arg 1 - Segment
  451.     push    si            ; Arg 2 - Offset
  452.     push    bx            ; Arg 3 - Display Line
  453.     push    cell            ; Arg 4 - Char/Attrib
  454.     call    CellWrt            ; Write line
  455.     push    SS            ; Restore DGroup
  456.     pop    DS            ; into DS register
  457.     pop    bx            ; Restore counter and
  458.     inc    bx            ; Count row displayed
  459.     cmp    ax,lbuffer        ; If position => end
  460.     jnc    pagedone        ; then page is done
  461.      mov    si,ax            ; else update pointer
  462.      cmp    bx,rows            ; If short of last row
  463.      jc    datloop            ; then loop Until done
  464.  
  465. pagedone:
  466.     mov    al,statatr        ; Load attribute for
  467.     mov    BYTE PTR cell[1],al    ; writing status line
  468.     mov    si,OFFSET statline
  469.     push    DS            ; Arg 1 - Segment
  470.     push    si            ; Arg 2 - Offset
  471.     push    bx            ; Arg 3 - Display Line
  472.     push    cell            ; Arg 4 - Char/Attrib
  473.     call    CellWrt            ; Write status line
  474.     mov    ES,sbuffer        ; Restore ES to buffer
  475.     pop    bp            ; Discard stack
  476.     ret    2            ; count argument
  477. Pager        ENDP
  478.  
  479. ; Procedure Retrace
  480. ; Purpose   Writes cell during horizontal retrace (CGA)
  481. ; Input    ES:DI has screen buffer position, AX has cell
  482. ; Output    Character to screen buffer
  483.  
  484. Retrace    PROC
  485.     push    bx
  486.     mov    bx,ax            ; Save character
  487.  
  488. lscan2:    in    al,dx            ; Look in the port
  489.     shr    al,1            ;   until it goes low
  490.     jc    lscan2
  491.  
  492.     cli
  493. hscan2:    in    al,dx            ; Look in the port
  494.     shr    al,1            ;   until it goes high
  495.     jnc    hscan2
  496.  
  497.     mov    ax,bx            ; Restore and write it
  498.     stosw
  499.     sti
  500.     pop    bx
  501.     ret
  502. Retrace    ENDP
  503.  
  504. ; Procedure CellWrt - Writes a line to screen buffer
  505. ; Input    Stack variables (segment,offset,line,cell)
  506. ; Output    Line to screen buffer
  507.  
  508. CellWrt    PROC
  509.     push    bp
  510.     mov    bp,sp
  511.     sub    dx,dx            ; Clear as flag for scan
  512.     cmp    cga,1            ; If NOT CGA
  513.     jne    noscan            ; then leave zero
  514.      mov    dx,03DAh        ; else load port #
  515. noscan:    mov    ES,vidadr        ; Load screen buffer segment
  516.     mov    DS,[bp+10]        ; Buffer segment
  517.     mov    si,[bp+8]        ; Buffer position
  518.     mov    cx,80            ; Cells per row
  519.     mov    ax,[bp+6]        ; Starting row
  520.     mov    bx,80*2            ; Bytes per row
  521.     mul    bl            ; Figure columns per row
  522.     mov    di,ax            ; Load as destination
  523.     mov    ax,[bp+4]        ; Set Attribute
  524. movechar:
  525.     lodsb                ; Get character
  526.     cmp    al,13            ; If End of Data Line
  527.     je    fillspc            ; then end display line
  528.     or    dx,dx            ; else if NOT CGA
  529.     je    notCGA            ; then Write without delay
  530.     call    Retrace            ; else Write during retrace
  531.     loop    movechar        ; until End of Data Line
  532.     jmp    SHORT nextline        ; or end of display line
  533.  
  534. notCGA:    stosw
  535.     loop    movechar        ; If end of display line
  536.     jmp    SHORT nextline        ; then find End of Data Line
  537.  
  538. fillspc:
  539.     mov    al," "            ; Fill with space
  540.     or    dx,dx            ; If NOT CGA
  541.     je    space2            ; then direct
  542. space1:    call    Retrace            ; else Write during retrace
  543.     loop    space1            ; until end of display line
  544.     inc    si            ; Adjust for Data line LF
  545.     jmp    SHORT exit        ; Done
  546.  
  547. space2:    rep    stosw            ; Write
  548.     inc    si            ; Adjust for LF
  549.     jmp    SHORT exit        ; Done
  550.  
  551. nextline:
  552.     mov    ah,10            ; Search for Data line feed
  553.  
  554. chklf:    lodsb                ; Load and compare
  555.     cmp    al,ah            ; If NOT Data Line LF
  556.     loopne  chklf            ; then contine until
  557. exit:    mov    ax,si            ; Return position
  558.     pop    bp
  559.     ret    8
  560. CellWrt    ENDP
  561.  
  562. GoForwd    PROC    ; Search Forward through buffer
  563. ; Input    CX has number of lines; ES:DI has buffer position
  564. ; Output    Updates "pbuffer" and DI index
  565.  
  566.     cld                ; Go forward
  567. findf:    mov    pbuffer,cx        ; Preserve count
  568.     mov    cx,0FFh            ; Load maximum character count
  569.     repne   scasb            ; If next LF NOT found
  570.     jcxz    atend            ; then must be at end
  571.     mov    cx,pbuffer        ; else If past end
  572.     cmp    di,lbuffer        ; then make at end
  573.     jae    atend            ; else loop until
  574.     loop    findf            ; at end or found
  575.     mov    pbuffer,di
  576.     call    EndCount        ; Get line number
  577.     mov    cx,lastnum        ; If last number
  578.     sub    cx,datrows        ; minus display
  579.     cmp    cx,linenum        ; is => linenum
  580.     jnc    GoForX            ; then pbuffer Ok
  581.  
  582. atend:    mov    di,lbuffer        ; Set index to end
  583.     mov    cx,datrows        ; Set page lines to
  584.     neg    cx            ; back-up during
  585.     mov    al,10            ; GoBack procedure
  586.     call    GoBack
  587. GoForX:    ret                ; Return pbuffer
  588. GoForwd    ENDP
  589.  
  590. GoBack    PROC    ; Search Backward through buffer
  591.     std                ; Go backward
  592.     neg    cx            ; Make count positive
  593.     inc    cx            ; Use one extra going up
  594. findb:    push    cx            ; Preserve counter
  595.     mov    cx,0FFh            ; Load maximum character count
  596.     cmp    cx,di            ; If NOT near start of buffer
  597.     jc    scanb            ; then use maximum count
  598.      mov    cx,di            ; else search only to start
  599.  
  600. scanb:    repne   scasb            ; If previous LF NOT found
  601.     jcxz    atstart            ; then must be at start
  602.     pop    cx            ; else loop until start/done
  603.     loop    findb
  604.     add    di,2            ; Adjust for cr/lf
  605.     jmp    SHORT GoBackX        ; Return position
  606. atstart:
  607.     pop    cx
  608.     sub    di,di            ; Set index and
  609. GoBackX:
  610.     mov    pbuffer,di        ; pointer and
  611.     ret                ; Return position
  612. GoBack    ENDP
  613.  
  614. BinToDStr   PROC
  615.     Comment ~    Right Justified Decimal ASCII String
  616.             Call With:  DX:AX = 32-bit value
  617.                     DS:DI after destination
  618.             Returns:    Registers UnChanged
  619.             ~
  620.     push    ax            ; Preserve
  621.     push    bx            ; All the
  622.     push    cx            ; Registers
  623.     push    dx            ; Used by
  624.     push    di            ; procedure
  625.     mov    cx,10            ; Set Divisor
  626. DivLoop:
  627.     call    Divide            ; Divide and
  628.     add    bl,"0"            ; Store ASCII
  629.     dec    di            ; Decimal Digit
  630.     mov    ES:[di],bl        ; Right to Left
  631.     mov    bx,ax            ; If 32-bits
  632.     or    bx,dx            ; NOT yet 0
  633.     jnz    DivLoop            ; Then Continue
  634.     pop    di            ; Else Restore
  635.     pop    dx            ; Registers to
  636.     pop    cx            ; Values on
  637.     pop    bx            ; Entry to
  638.     pop    ax            ; BinToDStr
  639.     ret
  640. BinToDStr   ENDP
  641.  
  642. Divide    PROC
  643.     push    ax            ; Preserve LSW
  644.     mov    ax,dx            ; Divide MSW as
  645.     xor    dx,dx            ; 32-bit Value
  646.     div    cx            ; Quotient
  647.     mov    bx,ax            ; in DX:BX
  648.     pop    ax            ; Divide LSW and
  649.     div    cx            ; Return DX:AX
  650.     xchg    bx,dx            ; Quotient and
  651.     ret                ; BX Remainder
  652. Divide    ENDP
  653.  
  654. Val2ASCh    PROC
  655.     mov    ah,al            ; Preserve byte value
  656.     and    al,0F0h            ; Isolate high
  657.     shr    al,1            ; nibble
  658.     shr    al,1            ; into
  659.     shr    al,1            ; low
  660.     shr    al,1            ; nibble
  661.     call    Val2Dig            ; Convert and Store
  662.     mov    al,ah            ; Restore byte value
  663.     and    al,0Fh            ; Isolate low nibble
  664. Val2Dig:
  665.     add    al,30h            ; Convert to display
  666.     cmp    al,3Ah            ; If decimal digit
  667.     jc    V2DI            ; then ASCII numeral
  668.      add    al,7            ; else make HEX alpha
  669. V2DI:    stosb                ; Store ASCII HEX
  670.     ret
  671. Val2ASCh    ENDP
  672.  
  673. ShoWord    PROC
  674.     push    ax            ; Preserve LSB
  675.     mov    al,ah            ; Isolate MSB
  676.     call    Val2ASCh        ; Store Digits 1 & 2
  677.     pop    ax            ; Restore LSB and
  678.     push    ax            ; save the Word
  679.     call    Val2ASCh        ; Store Digits 3 & 4
  680.     inc    di            ; plus a space
  681.     pop    ax            ; Return Word
  682.     ret
  683. ShoWord    ENDP
  684.  
  685. SortMCBs    PROC
  686.     mov    cx,bp            ; Restore Count of
  687.     dec    cx            ; Blocks Minus 1
  688.     xor    bx,bx            ; Zero Index and
  689.     xor    dx,dx            ; Flag NO Swaps
  690. SortLoop:
  691.     add    bx,8            ; Advance MCB Index
  692.     mov    ax,mcbs[bx].mcbf    ; Store
  693.     mov    mcbs.mcbf,ax        ; Flags
  694.     mov    ax,mcbs[bx].mcbl    ; length
  695.     mov    mcbs.mcbl,ax        ; MCB
  696.     mov    ax,mcbs[bx].mcba    ; and
  697.     mov    mcbs.mcba,ax        ; PSP
  698.     mov    ax,mcbs[bx].pspa    ; Addresses in
  699.     mov    mcbs.pspa,ax        ; base array member
  700.     cmp    ax,mcbs[bx+8].pspa    ; If PSPs Ascending
  701.     jle    LoopSort        ; then loop until done
  702.     dec    dx            ; else set sort flag
  703.     mov    ax,mcbs[bx+8].pspa    ;  and
  704.     mov    mcbs[bx].pspa,ax    ; swap
  705.     mov    ax,mcbs[bx+8].mcba    ; the
  706.     mov    mcbs[bx].mcba,ax    ; data
  707.     mov    ax,mcbs[bx+8].mcbl    ; for
  708.     mov    mcbs[bx].mcbl,ax    ; the
  709.     mov    ax,mcbs[bx+8].mcbf    ; two
  710.     mov    mcbs[bx].mcbf,ax    ; data
  711.     mov    ax,mcbs.mcbf        ; word
  712.     mov    mcbs[bx+8].mcbf,ax    ; table
  713.     mov    ax,mcbs.mcbl        ; array
  714.     mov    mcbs[bx+8].mcbl,ax    ; block
  715.     mov    ax,mcbs.mcba        ; members
  716.     mov    mcbs[bx+8].mcba,ax    ; until
  717.     mov    ax,mcbs.pspa        ; all
  718.     mov    mcbs[bx+8].pspa,ax    ; compared
  719. LoopSort:
  720.     loop    SortLoop
  721.     or    dx,dx            ; If Swaps
  722.     jnz    SortMCBs        ; Then Sort Again
  723.     ret                ; Until NO Swaps
  724. SortMCBs    ENDP
  725.  
  726. Chk4TSR    PROC
  727.     push    ax            ; Preserve
  728.     push    cx            ; Registers
  729.     push    di            ; Index and
  730.     push    ES            ; Extra Segment
  731.     mov    di,ES            ; Advance to
  732.     inc    di            ; Controlled Block
  733.     mov    ES,di            ; Segment and Area
  734.     mov    di,60h            ; for TSR Signature
  735.     mov    si,OFFSET watchS    ; "TSR WATCHER"
  736.     lodsb                ; If NO "T"
  737.     mov    cx,11            ; in 11 bytes
  738.     repne   scasb            ; Then Check
  739.     jne    C4Watch            ;  for Watch
  740.     cmpsw                ; Else If next 2
  741.     je    C4Texit            ; Then Exit Equal
  742. C4Watch:
  743.     mov    si,OFFSET watchS    ; "TSR WATCHER"
  744.     mov    di,81h            ; COMMAND LINE
  745.     mov    cx,11            ; PARAMETER
  746.     rep    cmpsb            ; RETURNS E or NE
  747. C4Texit:
  748.     pop    ES            ; Restore Segment
  749.     pop    di            ; Index and
  750.     pop    cx            ; General
  751.     pop    ax            ; Registers
  752.     ret
  753. Chk4TSR    ENDP
  754.  
  755. IsEnviron   PROC
  756.     mov    cx,mcbs[bx].mcba    ; Convert Environment
  757.     inc    cx            ; MCBA to Environment
  758.     mov    ES,cx            ; Segment and
  759.     mov    ax,mcbs[bx].mcbl    ; Convert Length in
  760.     mov    cl,4            ; Paragraphs to
  761.     shl    ax,cl            ; Length in
  762.     mov    cx,ax            ; Bytes
  763.     xor    di,di            ; Scan for
  764.     xor    ax,ax            ; Double Null
  765. SearchL:
  766.     repne   scasb            ; If First NOT
  767.     dec    cx            ; Followed by 2nd
  768.     scasb                ; Then Search
  769.     jcxz    NoFname            ; Until Environment End
  770.     jne    SearchL            ; OR Until Double Null
  771.     mov    al,"."            ; Scan for ".EXT"
  772.     repne   scasb            ; If NO Extent DOT
  773.     jcxz    NoFname            ; Then NO File Name
  774.     mov    cx,10            ; Else Look-Back for
  775.     mov    ax,":\"            ; Path Delimiter
  776. FnameLp:
  777.     dec    di            ; Until
  778.     cmp    ES:[di-1],al        ; Either
  779.     je    NameEnd            ; Find OR
  780.     cmp    ES:[di-1],ah        ; Fail to
  781.     je    NameEnd            ; Find Start of
  782.     loop    FnameLp            ; File Name
  783.  
  784. NoFname:
  785.     push    DS            ; Put Data Segment into
  786.     pop    ES            ; Extra Segment Register
  787.     mov    di,OFFSET doscm+4    ; Point into
  788.     mov    cx,3            ; "DOS<command..."
  789.  
  790. NameEnd:
  791.     mov    si,di            ; Set Source to Name
  792.     push    DS            ; Preserve Data Segment
  793.     push    ES            ; Transfer ES after
  794.     mov    ES,sbuffer        ; Restoring Buffer Segment
  795.     pop    DS            ; into DS Register and
  796.     mov    di,bp            ; Restore MapData Pointer
  797.     mov    dx,10            ; Calculate
  798.     sub    dx,cx            ; filename
  799.     xchg    dx,cx            ; length and
  800.     rep    movsb            ; store Owner and
  801.     add    di,dx            ; space to command line
  802.     pop    DS            ; Restore Data Segment
  803.     mov    si,OFFSET doscm+29    ; Point to "<environment>"
  804.     mov    cx,13            ; Store its length
  805.     rep    movsb            ; into command line and
  806.     add    di,6            ; advance to vectors
  807.     ret
  808. IsEnviron   ENDP
  809.  
  810. IsProgram   PROC
  811.     push    ax            ; Preserve PSP and
  812.     push    bx            ; mcbs Index Pointer
  813.     sub    bx,8            ; Backup to Environment MCB
  814.     call    IsEnviron        ; Get Owner Information
  815.     mov    cx,19            ; Backup to
  816.     sub    di,cx            ; Command and
  817.     mov    al," "            ; Space-It-Out
  818.     rep    stosb
  819.     sub    di,20            ; Restore Data
  820.     pop    bx            ; Pointer, mcbs
  821.     pop    ax            ; Index and PSP
  822.     ret
  823. IsProgram   ENDP
  824.  
  825. OwnComVec   PROC
  826.     push    cx            ; Preserve StoLoop Counter
  827.     inc    di            ; Advance to Owner
  828.     mov    bp,di            ; Preserve Pointer
  829.     mov    ax,mcbs[bx].mcbf    ; If Flags Show
  830.     or    ax,ax            ; is Trapped
  831.     jz    DOSblock        ; Then is DOS
  832.      mov    cx,mcbs[16].pspa    ; Else If DOS
  833.      cmp    cx,mcbs[bx].pspa    ; Is Below PSP
  834.      jc    Ck4Spec            ; Then check if Special
  835. DOSblock:
  836.     mov    si,OFFSET doscm        ; Else IS DOS
  837. ;v1.1    mov    cx,3            ; copy
  838. ;v1.1    rep    movsb            ; "DOS" and
  839.     movsw                ;copy 'DOS'            v1.1
  840.     movsb                ;                v1.1
  841.     add    di,7            ; space to command
  842.     or    ax,ax            ; If NOT Trapped
  843.     jnz    Which?            ; Then Check Which DOS
  844.      add    si,39            ; Else Advance to
  845.      mov    cx,9            ; "<trapped>"
  846.      jmp    SHORT MoveCmd
  847.  
  848. Which?:    mov    cx,13            ; If Second MCB
  849.     cmp    bx,16            ; Then "<command.com>"
  850.     je    MoveCmd            ; Else If First MCB
  851.     mov    si,OFFSET doscm+16    ; Then "<CONFIG.SYS> "
  852.     jc    MoveCmd            ; Else Must Be
  853.      add    si,cx            ; "<environment>"
  854.  
  855. MoveCmd:
  856.     rep    movsb            ; Move Command and
  857.     jmp    OCVExit            ; End the Line
  858.  
  859. Ck4Spec:
  860.     cmp    ax,-1            ; If NOT Special
  861.     jne    CkEnvir            ; Then Check If Environment
  862.     mov    ax,mcbs[bx].pspa    ; Else Load PSP
  863.     mov    ES,mcbs[bx].mcba    ; Point to MCB
  864.     call    Chk4TSR            ; If TSR WATCHER
  865.     cmp    si,OFFSET watchS+11    ; NOT Matched
  866.     jne    Ck4Mark            ; Then NOT Watch
  867.     mov    ES,sbuffer        ; Else Restore
  868.     mov    cx,11            ; Buffer and Copy
  869.     mov    si,OFFSET watchS    ; "TSR WATCHER"
  870.     rep    movsb            ; as Owner Name
  871.     push    DS            ; Set-Up for
  872.     mov    ax,17            ; Vectors
  873.     jmp    Go2Vecs
  874.  
  875. CkEnvir:
  876.     cmp    ax,0FFh            ; If NOT Environment
  877.     jne    Program            ; Then Must be Program
  878.     call    IsEnviron        ; Else IS Environment
  879.     jmp    OCVExit
  880.  
  881. Program:
  882.     mov    ax,mcbs[bx].pspa    ; Load the
  883.     call    IsProgram        ; Program PSP
  884.     push    DS            ; Preserve Data Segment
  885.     mov    DS,ax            ; Set to PSP and
  886.     jmp    SHORT CmdParm        ; Get Command Line
  887.  
  888. Ck4Mark:
  889.     push    DS            ; Preserve Data Segment
  890.     mov    ES,ax            ; Point into PSP at
  891.     mov    di,65h            ; [F]Mark signature
  892.     mov    si,OFFSET fmark+5    ; If "[F]M?.? TSR"
  893.     mov    cx,4            ; signature last
  894.     rep    cmpsb            ; 4 bytes match
  895.     jcxz    IsFMark            ; then is [F]Mark
  896.     dec    di            ; else check for loadtsr
  897.     rep    cmpsb            ; MenuTSR Identification
  898.     pop    DS            ; Restore Data and
  899.     mov    ES,sbuffer        ; MapData Buffer Segments
  900.     mov    di,bp            ; Restore MapData Pointer
  901.     mov    si,OFFSET doscm+4    ; Point to "command"
  902.     mov    cx,7            ; bytes and copy
  903.     jne    CyOwner            ; unless loadtsr
  904.      mov    si,OFFSET loadtsr    ; is the real
  905. CyOwner:
  906.     rep    movsb            ; Owner Area of MapData
  907.     je    OCVExit
  908. ;v1.1     add    di,2            ; Advance to Command Line
  909.      inc    di            ;advance to command line    v1.1
  910.      inc    di            ;v1.1
  911.      push    DS            ; Preserve Data Segment
  912.      mov    DS,ax            ; Set to PSP and
  913.      jmp    SHORT CmdParm        ; Get Command Line
  914.  
  915. IsFMark:
  916.     push    ES            ; Put PSP Segment AFTER
  917.     mov    ES,sbuffer        ; Restore MapData Buffer
  918.     pop    DS            ; into DS Register
  919.     mov    si,di            ; Set Source Index to
  920.     mov    cx,9            ; beginning of the
  921.     sub    si,cx            ; [F]Mark signature
  922.     mov    di,bp            ; Segment and Pointer
  923.     rep    movsb            ; Copy FMark Signature
  924. CmdParm:
  925.     inc    di            ; Presume NO White Space
  926.     mov    si,81h            ; Get Command Length and
  927.     mov    cx,[si-1]        ; 1st Command Line Byte
  928.     cmp    ch,"!"            ; Check for White Space OR
  929.     mov    ch,0            ; If NO Parameter Length
  930.     jcxz    Go2Vecs            ; Then Adjust to Vectors
  931.  
  932.     jnc    NoSpace            ; Else Ready with No Space
  933.      dec    di            ; Else Make Room for Space
  934. NoSpace:
  935.     cmp    cx,19            ; If Don't Need elipsis
  936.     jle    CopyCmd            ; Then copy all bytes
  937.      mov    cx,16            ; else copy 16 bytes
  938.      mov    ax,".."            ; adding continuation
  939. CopyCmd:
  940.     cmp    byte ptr DS:[si]," "
  941.     jc    NotCopy            ; If Printable
  942.      movsb                ; Then Copy
  943.      jmp    Short CpyLoop        ;  and Loop
  944.  
  945. NotCopy:
  946.     inc    si            ; Else Replace
  947.     inc    di            ; With Space
  948. CpyLoop:
  949.     loop    CopyCmd            ;  and Loop
  950.     cmp    ax,".."            ; If NOT continuation
  951.     jne    Go2Vecs            ; Then Vectors
  952.      stosw                ; Else continue
  953.      stosb                ; elipsis (...)
  954. Go2Vecs:
  955.     pop    DS            ; Restore Data Segment
  956.     mov    ax,mcbs[bx].mcba    ; If Memory Control Block
  957.     inc    ax            ; Segment Address + 1
  958.     cmp    ax,mcbs[bx].pspa    ; is NOT EQUAL to PSP
  959.     jne    OCVExit            ; then NO Interrupts
  960.      call    Vectors            ; else store vectors
  961. OCVExit:
  962.     mov    ax,0A0Dh        ; End the Data
  963.     stosw                ; Storage Line
  964.     pop    cx            ; Restore StoLoop Counter
  965.     ret
  966. OwnComVec   ENDP
  967.  
  968. GetData    PROC
  969.     mov    ah,52h            ; Use reserved DOS
  970.     int    21h            ; Interrupt to get
  971.     mov    bp,ES:[bx-2]        ; Start MCB Address
  972.     xchg    bx,dx            ; Zero Array Index
  973. MCBLoop:
  974.     add    bx,8            ; Advance Index
  975.     mov    ES,bp            ; Locate MCB and
  976.     inc    bp            ; Block Segments
  977.     mov    ax,ES:[1]        ; Get PSP and
  978.     mov    cx,ES:[3]        ; Block Length
  979.     cmp    ax,bx            ; If CONGIG PSP
  980.     je    FixPSP            ; Then Fix to MCB+1
  981.     or    ax,ax            ; Else If NOT Trapped
  982.     jnz    CkBlock            ; Then Flag NOT 0
  983.      xor    dx,dx            ; Else Zero mcbs Flag
  984. FixPSP:     mov    ax,bp            ; Set Block = MCB+1
  985.      jmp    SHORT PutTable
  986.  
  987. CkBlock:
  988.     cmp    ax,bp            ; If PSP NOT MCB+1
  989.     mov    dx,0FFh            ; Then Flag Environment
  990.     jnz    PutTable        ;  for MCB Table Item
  991.     xchg    dh,dl            ; Else Flag as Program
  992.     call    Chk4TSR            ; If NOT [F]Mark, Watch, etc
  993.     jne    PutTable        ; Then Flag as "Program"
  994.      mov    dl,dh            ; Else Flag as "Special"
  995. PutTable:
  996.     mov    mcbs[bx].mcba,ES    ; Store MCB Address
  997.     mov    mcbs[bx].pspa,ax    ; Store PSP Address
  998.     mov    mcbs[bx].mcbl,cx    ; Length of Block and
  999.     mov    mcbs[bx].mcbf,dx    ; Flag Word of Type Block
  1000.     cmp    BYTE PTR ES:[0],"Z"    ; If Last MCB
  1001.     je    LastMCB            ; Then MCBs done
  1002.      add    bp,cx            ; Else Next MCB
  1003.      jmp    short MCBLoop        ; Until Last
  1004.  
  1005. LastMCB:
  1006.     mov    ES,sbuffer        ; Set Buffer Segment
  1007.     mov    cx,3            ; Calculate and
  1008.     shr    bx,cl            ; Store Block
  1009.     mov    bp,bx            ; Count
  1010.     call    SortMCBs        ; Sort Blocks by PSP
  1011.     mov    cx,bp            ; ReStore Counter and
  1012.     xor    bx,bx            ; Index to Beginning
  1013. StoLoop:
  1014.     add    bx,8            ; Advance MCB Index
  1015.     mov    ax,mcbs[bx].pspa    ; Get PSP Address Word
  1016.     mov    startl,di        ; UpDate Start of Line
  1017.     inc    di            ; Start with a space
  1018.     call    ShoWord            ; Display PSP in HEX
  1019.     mov    ax,mcbs[bx].mcba    ; Get MCB Address Word
  1020.     call    ShoWord            ; Display 4 HEX Digits
  1021.     mov    ax,mcbs[bx].pspa    ; Restore PSP
  1022.     cmp    spsp,ax            ; If ShowTSRs
  1023.     je    WasLast            ; Then End Table
  1024.     mov    dx,mcbs[bx].mcbf    ; If Flag Shows
  1025.     cmp    dh,0FFh            ; NOT TSR Program
  1026.     jne    FilExit            ; then skip files
  1027.  
  1028.     mov    ES,ax            ; Point to Segment and
  1029.     mov    di,18h            ; Offset of DOS Files
  1030.     mov    cx,20            ; Initialize Counter
  1031.     mov    al,0FFh            ; Looking for closed
  1032.     repne   scasb            ; Preserve position
  1033.     mov    ax,di            ; after search
  1034.     mov    ES,sbuffer        ; Restore Data Buffer
  1035.     sub    ax,19h            ; Calculate open files
  1036.     xor    dx,dx            ; as a double word to
  1037.     mov    di,startl        ; place under "l" in
  1038.     add    di,14            ; "file" heading
  1039.     call    BinToDStr
  1040. FilExit:
  1041.     mov    ax,mcbs[bx].mcbl    ; Store length as
  1042.     jmp    SHORT P2Bytes        ; decimal bytes
  1043.  
  1044. WasLast:
  1045.     mov    ax,fmem            ; Store free
  1046.     mov    si,offset freem+2    ; "free" RAM
  1047.     mov    cx,4            ; message
  1048.     rep    movsb            ; Counter = 0 to END
  1049.  
  1050. P2Bytes:
  1051.     push    cx            ; Preserve Counter
  1052.     xor    dx,dx            ; Clear top and
  1053.     mov    cx,10h            ; multiply into
  1054.     mul    cx            ; double word
  1055.     mov    di,startl        ; value for
  1056.     add    di,22            ; "bytes"
  1057.     call    BinToDStr
  1058.     pop    cx            ; If Counter is Zero
  1059.     jcxz    EndMCBs            ; then MCBs are done
  1060.      call    OwnComVec        ; else finish line
  1061.      jmp    StoLoop            ; Until Last Line
  1062.  
  1063. EndMCBs:
  1064.     mov    ax,0A0Dh        ; End the
  1065.     stosw                ; Last Line
  1066.     call    InfoMap            ; Add EGA & ICA Info
  1067.     mov    si,OFFSET emsname    ; and If Driver Found
  1068.     call    EmmsMap            ; add EMS Information
  1069.     ret
  1070. GetData    ENDP
  1071.  
  1072. DoIMdata    PROC
  1073.     push    DS            ; Preserve Data Segment
  1074.     push    ax            ; and Pointer to DOS Data
  1075.     mov    si,ax            ; Initialize Source Index
  1076.     mov    cx,8            ; Pointer and Counter
  1077.     mov    ax,40h            ; Set DOS data segment in
  1078.     mov    DS,ax            ; Data Segment Register
  1079.     cmp    si,0A8h            ; If EGA Info Area
  1080.     jz    IMAOk            ; then bytes IS 8
  1081.      add    cx,8            ; else bytes is 16
  1082. IMAOk:    push    cx            ; Preserve byte counter
  1083.  
  1084. IMdigL:    inc    di            ; Space before
  1085.     lodsb                ; and Store 2
  1086.     call    Val2ASCh        ; HEX ASCII digits
  1087.     loop    IMdigL            ; until count complete
  1088.     pop    cx            ; Restore byte counter
  1089.     pop    si            ; and DOS data pointer
  1090. ;v1.1    add    di,2            ; Add 2 spaces
  1091.     inc    di            ;add 2 spaces            v1.1
  1092.     inc    di            ;v1.1
  1093.     cmp    si,0A8h            ; If NOT 8 byte EGA
  1094.     jnz    IMascL            ; then ready for ASCII
  1095.      add    di,8            ; else need 8 spaces
  1096. IMascL:    lodsb                ; Get a byte
  1097.     cmp    al,20h            ; If => space
  1098.     jnc    CkHigh            ; then check delete
  1099. UseDot:     mov    al,"."            ; else use a dot
  1100.  
  1101. CkHigh:    cmp    al,7Fh            ; If => space
  1102.     jnc    UseDot            ; then use a dot
  1103.     stosb                ; Send to MapData
  1104.     loop    IMascL            ; until CX 'em
  1105.  
  1106.     pop    DS            ; Restore Data Segment
  1107.     mov    ax,0A0Dh        ; End the line
  1108.     stosw
  1109.     ret
  1110. DoIMdata    ENDP
  1111.  
  1112. InfoMap    PROC
  1113.     call    Underline        ; Underline block data
  1114.     mov    si,OFFSET egahdg    ; Transfer EGA Info
  1115.     mov    cx,EGALEN        ; Area Heading
  1116.     rep    movsb
  1117.     mov    ax,0A8h            ; Point to and
  1118.     call    DoIMdata        ; transfer EGA data
  1119.     mov    si,OFFSET icahdg    ; Transfer Inter-
  1120.     mov    cx,ICALEN        ; Application Area
  1121.     rep    movsb            ; Heading bytes
  1122.     mov    ax,0F0h            ; Point to and
  1123.     call    DoIMdata        ; get ICA data
  1124. Underline:
  1125.     mov    ax,"- "
  1126.     stosb                ; Space plus
  1127.     mov    al,ah            ; Minus sign
  1128.     mov    cx,76            ; Underlines
  1129.     rep    stosb
  1130.     mov    ax,0A0Dh        ; End the
  1131.     stosw                ; underline
  1132.     ret
  1133. InfoMap    ENDP
  1134.  
  1135. EmmsMap    PROC
  1136.     mov    ax,3567h        ; Get Vector for
  1137.     int    21h            ; Function 67hex
  1138.     push    di            ; Preserve store pointer
  1139.     mov    di,000Ah        ; If Device
  1140.     mov    cx,8            ; Name is NOT
  1141.     rep    cmpsb            ; "EMMXXXX0"
  1142.     mov    ES,sbuffer        ; after restore
  1143.     pop    di            ; storage ES:DI
  1144.     jne    EmsErrX            ; then Error Exit
  1145.     mov    ah,46h            ; or if version
  1146.     int    67h            ; number request
  1147.     or    ah,ah            ; returns error
  1148.     jnz    EmsErrX            ; then Error Exit
  1149.  
  1150.     mov    si,OFFSET emmshdg    ; else store 1st
  1151.     mov    cx,EMMLEN1        ; heading line
  1152.     rep    movsb            ; with Version
  1153.     call    Val2ASCh        ; Major Number
  1154.     mov    ah,"."            ; plus dot and
  1155.     xchg    al,ah            ; Minor Number
  1156.     dec    di
  1157.     stosw
  1158.     mov    cx,EMMLEN2        ; Add 2nd heading
  1159.     rep    movsb            ; line lead-in to
  1160.     mov    ah,41h            ; EMS Page Frame
  1161.     int    67h            ; If Page Frame
  1162.     or    ah,ah            ; Request Fails
  1163.     jnz    EmsErrX            ; then Error Exit
  1164.     mov    al,bh            ; else store HEX
  1165.     call    Val2ASCh        ; first two digits
  1166.     mov    al,bl            ; third and fourth
  1167.     call    Val2ASCh        ; plus ending
  1168.     mov    al,")"            ; parenthesis
  1169.     stosb
  1170.     mov    ax,0A0Dh        ; End the line
  1171.     stosw
  1172.     mov    ah,4Bh            ; Get Handle
  1173.     int    67h            ; Count in BX
  1174.     or    ah,ah            ; If Response
  1175.     jz    EmPages            ; then Map Pages
  1176.  
  1177. EmsErrX:
  1178.     mov    si,OFFSET emserm    ; else store
  1179.     mov    cx,EMERML        ; E M S
  1180.     rep    movsb            ; Error
  1181.     jmp    EmmExit            ; Message
  1182.  
  1183. EmPages:
  1184.     mov    cx,bx            ; Set Handle Counter
  1185.     inc    cx            ; for zero thru [bx]
  1186.     xor    dx,dx            ; Count up from 0
  1187. HndLoop:
  1188.     mov    startl,di        ; Save Start of Line
  1189.     mov    ah,4Ch            ; Get Assigned
  1190.     int    67h            ; Handle Pages
  1191.     or    ah,ah            ; If Error
  1192.     jnz    NoPages            ; then skip
  1193.      or    bx,bx            ; else if > 0
  1194.      jnz    PagesOk            ; then store
  1195. NoPages:
  1196.     inc    dx            ; else loop until
  1197.     loop    HndLoop            ; CX handles done
  1198.     jmp    SHORT HndExit
  1199.  
  1200. PagesOk:
  1201.     add    di,6            ; Position for
  1202.     push    dx            ; Handle Number
  1203.     xor    ax,ax            ; Double Word
  1204.     xchg    ax,dx            ; Digit(s)
  1205.     call    BinToDStr
  1206.     add    di,9            ; Position for
  1207.     mov    ax,bx            ; Handle Pages
  1208.     call    BinToDStr
  1209.     add    tpages,ax        ; Accumulate Total
  1210.     add    di,9            ; Position for
  1211.     mov    bx,16            ; Kilo
  1212.     mul    bx            ; Bytes
  1213.     call    BinToDStr
  1214.     pop    dx            ; Restore Handle
  1215.     add    di,3            ; Position for
  1216.     mov    ax,5300h        ; User Name
  1217.     int    67h            ; Advance Past
  1218.     add    di,8            ; Name Area and
  1219.     mov    ax,0A0Dh        ; End the line
  1220.     stosw
  1221.     inc    dx            ; Increment Handle
  1222.     loop    HndLoop            ; until CX'em done
  1223.  
  1224. HndExit:
  1225.     mov    ah,42h            ; Get Free
  1226.     int    67h            ; Pages
  1227.     mov    ax,tpages        ; Calculate and
  1228.     add    ax,bx            ; Preserve
  1229.     push    ax            ; Total Pages
  1230.     mov    si,OFFSET freem        ; Store the
  1231. ;v1.1    mov    cx,6            ; "  free"
  1232. ;v1.1    rep    movsb            ; lead-in
  1233.     movsw                ;3 words            v1.1
  1234.     movsw
  1235.     movsw
  1236.     add    di,9            ; Position for
  1237.     mov    ax,bx            ; Free Pages
  1238.     xor    dx,dx            ; DoubleWord
  1239.     call    BinToDStr
  1240.     add    di,9            ; Position for
  1241.     mov    bx,16            ; Free Kilo
  1242.     mul    bx            ; Bytes
  1243.     call    BinToDStr
  1244.     mov    si,OFFSET dashes+24    ; Space Over
  1245.     mov    cx,11            ; and dash-out
  1246.     rep    movsb            ; UserName
  1247.     mov    ax,0A0Dh        ; End the line
  1248.     stosw
  1249.     mov    si,OFFSET totlm        ; Store
  1250. ;v1.1    mov    cx,6            ; " total"
  1251. ;v1.1    rep    movsb            ; lead-in
  1252.     movsw                ; ' total'            v1,1
  1253.     movsw                ;lead-in            v1,1
  1254.     movsw                ;(6 chars)            v1,1
  1255.     add    di,9            ; Position for
  1256.     pop    ax            ; Total
  1257.     call    BinToDStr        ; Pages
  1258.     add    di,9            ; Position for
  1259.     mul    bx            ; Total Bytes
  1260.     call    BinToDStr
  1261.     mov    si,OFFSET dashes+24    ; Space Over
  1262.     mov    cx,11            ; and dash-out
  1263.     rep    movsb            ; UserName
  1264.  
  1265. EmmExit:
  1266.     mov    ax,0A0Dh        ; End the line
  1267.     stosw
  1268.     ret
  1269. EmmsMap    ENDP
  1270.  
  1271. Vectors    PROC
  1272.     mov    si,OFFSET watchS    ; If the
  1273.     mov    di,startl        ; Owner
  1274.     add    di,23            ; Name was NOT
  1275.     mov    cx,11            ; "TSR WATCHER"
  1276.     rep    cmpsb            ; Then Check If
  1277.     jnz    CkWatch            ; Already Installed
  1278.      mov    watchF,ax        ; Else Flag Installed
  1279. CkWatch:
  1280.     mov    di,startl        ; Position Index to
  1281.     add    di,51            ; Start of Vector Area
  1282.     cmp    watchF,0        ; If NO TSR WATCHER Installed
  1283.     jz    UseHook            ; Then Use Hooked Vectors
  1284.     push    DS            ; Else Use Chained
  1285.     mov    DS,watchF        ; Vectors from Watch
  1286.     mov    dx,ax            ; Copy Program PSP
  1287.     mov    si,104h            ; Get Next Vector
  1288.     lodsw                ; Position in
  1289.     mov    si,218h            ; Vector Change
  1290.     add    ax,220h            ; Storage Area
  1291.     mov    vpos,ax            ; Store for Comparison
  1292.     xor    bp,bp            ; Zero Vector Counter
  1293. FFLoop:    add    si,8            ; If Next Record
  1294.     cmp    si,vpos            ; Is => Table End
  1295.     jnc    WatchX            ; then exit done
  1296.     cmp    BYTE PTR [si],0FFh    ; else if NOT pspid
  1297.     jne    FFLoop            ; or if PSP
  1298.     cmp    [si+2],dx        ; is NOT desired PSP
  1299.     jne    FFLoop            ; then keep looking
  1300.  
  1301. WatchL:    add    si,8            ; If Next Record
  1302.     cmp    si,vpos            ; is => Table End
  1303.     jnc    WatchX            ; Then exit done
  1304.     cmp    WORD PTR [si],-1    ; Else If Next pspid
  1305.     jnc    WatchX            ; then exit done
  1306.     cmp    BYTE PTR [si+1],1    ; else if NOT disabled
  1307.     jne    WatchV            ; then put vectors
  1308.     pop    DS            ; else restore data
  1309.     mov    si,OFFSET disam        ; segment of message
  1310.     mov    cx,DISALEN        ; ***D I S A B L E D
  1311.     rep    movsb            ; *** and exit
  1312.     jmp    SHORT INTExit
  1313.  
  1314. WatchV:    cmp    bp,9            ; If NOT to last column
  1315.     jc    WatchW            ; then store Vector
  1316.     mov    WORD PTR ES:[di],0A0Dh
  1317.     add    di,53            ; else start new line
  1318.     xor    bp,bp            ;  and update counter
  1319. WatchW:    mov    ax,[si]            ; Get Vector Number
  1320.     call    Val2ASCh        ; Store 2 HEX ASCII
  1321.     inc    di            ; digits plus a space
  1322.     inc    bp            ; Count Vector
  1323.     jmp    SHORT WatchL        ; Loop until exit
  1324.  
  1325. WatchX:    pop    DS            ; Restore Data
  1326.     jmp    SHORT INTExit        ; Segment and Exit
  1327.  
  1328. UseHook:
  1329.     mov    bp,di            ; Copy Pointer
  1330.     xor    di,di            ; Point ES:DI to
  1331.     mov    ES,di            ; DOS INT Vectors
  1332.     mov    cx,512            ; Set Word Count
  1333.     mov    dx,4            ; and INT Divisor
  1334. INTLoop:
  1335.     mov    ax,mcbs[bx].pspa    ; Scan for PSP in
  1336.     repne   scasw            ; DOS Vector Table
  1337.     mov    ES,sbuffer        ; Restore ES:DI to Buffer
  1338.     xchg    bp,di            ; If at End of Vector Table
  1339.     jcxz    INTExit            ; then Vectors are Done
  1340.     mov    ax,bp            ; else Calculate
  1341.     div    dl            ; Vector Number
  1342.     dec    ax            ; Zero - Based
  1343.     call    Val2ASCh        ; Display 2 HEX ASCII
  1344.     inc    di            ; digits plus a space
  1345.     xor    ax,ax            ; Reset Extra Segment
  1346.     mov    ES,ax            ; and Pointer to Vectors
  1347.     xchg    bp,di            ; preserving MapData Pointer
  1348.     mov    ax,startl        ; If start of current row
  1349.     add    ax,COLUMNS-3        ; to position after end
  1350.     cmp    bp,ax            ; is greater than pointer
  1351.     jc    INTLoop            ; then loop until end/done
  1352.     mov    WORD PTR ES:[bp],0A0Dh
  1353.     add    bp,53            ; else start new line
  1354.     jmp    SHORT INTLoop        ; Loop Until Vectors Done
  1355.  
  1356. INTExit:
  1357.     ret
  1358.  
  1359. Vectors    ENDP
  1360.  
  1361.     END    Main
  1362.  
  1363.     This Version 3.1 revision began with a complaint that
  1364.     "garbage was displayed" for certain TSR command lines.
  1365.  
  1366.     The cause was a programming error in that a 0 Length
  1367.     command line was NOT skipped.  The revision result is
  1368.     a ShowTSRs that reverts to the original purpose.  It
  1369.     is again compatible with all [F]MarkS, watchS, etc...
  1370.     whether from TurboPower or Tom Gilbert's Heart & Mind.
  1371.  
  1372.     We are learning from the experience and will welcome comments
  1373.     or criticism...  I lied!  We'd rather have help and praise...
  1374.