home *** CD-ROM | disk | FTP | other *** search
/ TopWare Tools / TOOLS.iso / tools / top1190 / menutsrs.asm < prev    next >
Encoding:
Assembly Source File  |  1989-05-31  |  34.0 KB  |  705 lines

  1. Title   MenuTSRs.ASM -- Load TSRs via Load2TSR.BAT from MENU
  2. Subttl                       V3.1 --- 30-May-1989 - 03:10:00
  3. _DATA Segment Para Memory 'DATA'
  4. UsageMsg                                                DB  13,10,9
  5. DB 'MenuTSRs 3.1 provides a MENU of TSRs for Load2TSR.BAT.',13,10,9
  6. DB '======================================================',13,10,9
  7. DB 'You can avoid input of the TSRdir and MrkDir variables',13,10,9
  8. DB 'by using the SET command to SET the environment BEFORE',13,10,9
  9. DB 'calling MenuTSRs, but; there are more requirements:',13,10,10,9
  10. DB 'WATCH 3.1 MUST HAVE a File-Mark and be the ONLY memory',13,10,9
  11. DB 'resident program when MenuTSRs is INITIALLY activated!',13,10,10,9
  12. DB 'MenuTSRs will provide a list of TSRs in the TSRdir and',13,10,9
  13. DB 'display either "DISK" if NOT YET installed or the PSPA',13,10,9
  14. DB 'in HEX if they are currently installed and [F]Marked.',13,10,10,9
  15. DB 9,'File-Marks will be placed ahead of each TSR',13,10,9
  16. DB 9,'that is installed.  UnMark and MenuTSRs can',13,10,9
  17. DB 9,'be used in sequence to replace TSRs.  Note:',13,10,9
  18. DB 9,'MenuTSRs is called by TSRmenu.BAT because a',13,10,9
  19. DB 9,'Load2TSR.BAT file is created to LOAD TSR(s)',13,10,9
  20. DB 9,'by chaining when MenuTSRs returns.',13,10,10,9,'Command Syntax:'
  21. TSRmenu DB 13,10,10,9,9,9,'prompt >TSRmenu',13,10,"$",8,32,26
  22. Display DB 13,10,10                     ; You can >TYPE MenuTSRs.EXE
  23. EVTSR   DB  'TSRdir=',25 DUP(0),13,10
  24. EVMrk   DB  'MrkDir=',25 DUP(0),13,10
  25. WaTSR   DB  'Watch PSP    NONE',13,10,10
  26.     DB  'TSR FileName Status  MENU  '
  27.         DB  'TSR FileName Status',13,10
  28. TSR01    DB  '             NONE          '
  29. TSR13   DB  '             NONE  ',13,10
  30. TSR02    DB  '             NONE          '
  31. TSR14   DB  '             NONE  ',13,10
  32. TSR03    DB  '             NONE          '
  33. TSR15   DB  '             NONE  ',13,10
  34. TSR04    DB  '             NONE          '
  35. TSR16   DB  '             NONE  ',13,10
  36. TSR05    DB  '             NONE          '
  37. TSR17   DB  '             NONE  ',13,10
  38. TSR06    DB  '             NONE          '
  39. TSR18   DB  '             NONE  ',13,10
  40. TSR07    DB  '             NONE          '
  41. TSR19   DB  '             NONE  ',13,10
  42. TSR08    DB  '             NONE          '
  43. TSR20   DB  '             NONE  ',13,10
  44. TSR09    DB  '             NONE          '
  45. TSR21   DB  '             NONE  ',13,10
  46. TSR10    DB  '             NONE          '
  47. TSR22   DB  '             NONE  ',13,10
  48. TSR11    DB  '             NONE          '
  49. TSR23   DB  '             NONE  ',13,10
  50. TSR12    DB  '             NONE          '
  51. TSR24   DB  '             NONE  ',13,10,10
  52. Prompt  DB  'Enter TSRfile name [parameter(s)] <END>:',13,10,10,255
  53. MarkID  DB  'FM3.1 TSR WATCHER'         ; IDs of FMark and Watch
  54. ReqVar  DB  'Enter Drive:[\Path] for $' ; Request for directories
  55. BatDat  DB  'Echo.',13,10,'Echo Off',13,10,'KillLOAD',13,10,13,10
  56. FMark   DB  'FMark \Load2TSR.BAT',0     ; Three Lines of Multi-Data Items
  57. Disk    DB  'DISKLOAD',80h DUP(?)
  58. DTA     DB  43 DUP(0)                   ; Storage for File Control Block
  59. align   16
  60. MenuPSP DW  ?                           ; Storage for PSP of MenuTSRs
  61. MenuENV DW  ?                           ; and SEG of its Environment
  62. EnvSEG  DW  ?                           ; Storage for SEGment and
  63. EnvLen  DW  ?                           ; Length of DOS Environment
  64. WatchF  DW  0                           ; PSP of Watch 3.1 Resident
  65. ResidF  DW  0                           ; PSP of MenuTSRs Resident
  66. CurPos  DW  ?                           ; Stored Row and Column
  67. ErrLvl  DW  4C00h                       ; Error Level Exit Word
  68. MCBbuf  DW      100h    DUP(0)          ; MCB Table start OFFset
  69. _DATA   EndS
  70. _STACK  Segment Para    Stack   'STACK'
  71.         DB      100h    DUP(0)
  72. _STACK  EndS
  73. _TEXT   Segment Para    Public  'CODE'
  74.         Assume  cs:_TEXT,ds:_DATA,es:Nothing,ss:_STACK
  75. Main    Proc    Far
  76.         mov     ax,_DATA                ; Make DATA
  77.         mov     ds,ax                   ; Addressable
  78.         mov     MenuPSP,es              ; Store PSP
  79.         mov     ax,es:[2Ch]             ; and SEG of
  80.         mov     MenuENV,ax              ; Environment
  81.         mov     ah,52h                  ; Undocumented
  82.         int     21h                     ; Function
  83.         mov     di,es:[bx-2]            ; to obtain
  84.         mov     es,di                   ; MCB of DOS
  85.         inc     di                      ; Config.Sys
  86.         add     di,es:[3]               ; Advance to
  87.         mov     es,di                   ; MCB of DOS
  88.         inc     di                      ; Command.Com
  89. GetEnv: add     di,es:[3]               ; Advance to
  90.         mov     es,di                   ; MCB of DOS
  91.         inc     di                      ; Environment
  92.         cmp     word ptr es:[1],0       ; If Trapped
  93.         jz      GetEnv                  ; Then NOT ENV
  94.         mov     EnvSEG,di               ; Else Store Segment
  95.         mov     ax,es:[3]               ; Convert from
  96.         mov     cx,4                    ; Paragraphs to
  97.         shl     ax,cl                   ; Bytes and Store
  98.         mov     cx,ax                   ; Length in Bytes of
  99.         mov     EnvLen,cx               ; Master Environment
  100.         call    GetDirs                 ; Get TSRdir & MrkDir
  101.         mov     si,offset MCBbuf        ; Set MCB
  102.         xor     bx,bx                   ; Indices
  103. MCBlp:  add     di,es:[3]               ; Advance so as to
  104.         mov     es,di                   ; Point to MCB and
  105.         inc     di                      ; Next Paragraph
  106.         mov     [si+bx+0],es            ; Store MCB
  107.         mov     dx,es:[1]               ; Get and Store
  108.         mov     [si+bx+2],dx            ; Block Address
  109.         mov     ax,es:[3]               ; and Block
  110.         mov     [si+bx+4],ax            ; Length
  111.         call    DoFlags                 ; Set Appropriate Flags
  112.         add     bx,8                    ; Advance to Next and
  113.         cmp     byte ptr es:[0],"Z"     ; Loop Until Last MCB
  114.         jne     MCBlp                   ; Table Entry Complete
  115.         mov     ax,_DATA                ; Restore Extra
  116.         mov     es,ax                   ; Segment to DATA
  117.         mov     di,si                   ; Scan the Blocks for
  118.         mov     ax,-1                   ; First File-Mark Block
  119.         mov     bp,WatchF               ; Looking for Watch Mark
  120.         mov     cx,bx                   ; Convert Bytes to
  121.         shr     cx,1                    ; Words in MCB to Scan
  122.         repne   scasw                   ; If a File-Mark
  123.         je      Watch?                  ; Then See If Watch
  124.         mov     byte ptr ErrLvl,1       ; Else NO File-Mark
  125. Usage:  mov     ah,9                    ; Error Exit
  126.         mov     dx,offset UsageMsg      ; With Help
  127.         int     21h                     ; Message
  128.         jmp     Exit
  129.  
  130. Watch?: cmp     es:[di+2],bp            ; If 1st TSR IS Watch
  131.         je      Ck4TSR                  ; Then Check for MenuTSRs
  132.         mov     byte ptr ErrLvl,2       ; Else NO Watch Error
  133.         jmp     Short Usage             ; Exit With Help Message
  134.  
  135. Ck4TSR: push    di                      ; Preserve Pointer
  136.         mov     di,offset WaTSR+13      ; Store Watch
  137.         call    BP2PSPA                 ; PSP Address
  138.         pop     di                      ; Restore Pointer
  139.         mov     ax,ResidF               ; If MenuTSRs
  140.         or      ax,ax                   ; IS Resident
  141.         jne     DoDisp                  ; Or If NO Other
  142.         repne   scasw                   ; TSR Follows
  143.         repne   scasw                   ; After Watch TSR
  144.         jne     DoDisp                  ; Then Fill-Out Display
  145. NoTSRs: mov     byte ptr ErrLvl,3       ; Else Error Exit With Help
  146.         jmp     Short Usage
  147. DoDisp: mov     ah,1Ah                  ; Set Data
  148.         mov     dx,offset DTA           ; Transfer
  149.         int     21h                     ; Area
  150.         mov     si,offset EVTSR+7       ; Copy TSRdir
  151.         mov     di,offset DTA           ; path to DTA
  152.         mov     ax,"*\"                 ; up to Null
  153. EndChk: cmp     byte ptr [si],0         ; If Null
  154.         jz      EndDir                  ; Then Path Done
  155.         movsb                           ; Else Copy More
  156.         jmp     short EndChk
  157. EndDir: stosw                           ; Add "\*"
  158.         mov     ax,"C."                 ; and ".COM"
  159.         stosw                           ; filespec
  160.         mov     ax,"MO"                 ; ASCIIZ
  161.         stosw                           ; string
  162.         movsb
  163.         mov     ah,4Eh                  ; If Find
  164.         mov     dx,offset DTA           ; First of
  165.         mov     cx,7                    ; ANY .COM
  166.         int     21h                     ; File Fails
  167.         jc      FilEnd                  ; Then Display NONE
  168.         mov     di,offset TSR01-44      ; Else Initialize Pointer
  169. CpyNxt: add    di,48            ; Copy File
  170.         mov     si,offset DTA+30        ; Name
  171.         mov     cx,9                    ; Bytes
  172. MovNxt: movsb                           ; up to
  173.         cmp     byte ptr [si],"."       ; period
  174.         loopne  MovNxt
  175.         add     di,cx                   ; If Installed
  176.         call    IfPSPA                  ; Then "PSPA"
  177.         jnc     NxtFil                  ; Status
  178.         mov     si,offset Disk          ; Else "DISK"
  179.         mov     cx,4                    ; Status
  180.         rep     movsb
  181. NxtFil: mov     ah,4Fh                  ; If Find
  182.         int     21h                     ; Next Fails
  183.         jc      FilEnd                  ; Then Done
  184.         sub     di,13                   ; Else If More
  185.         cmp     di,offset TSR12+4       ; Lines to go
  186.         jc      CpyNxt                  ; Then Copy Next
  187.         cmp     di,offset TSR24+4       ; Else If Full Menu
  188.         jnc     FilEnd                  ; Then End of Files
  189.         mov     di,offset TSR13-44      ; Else Re-Initialize
  190.     jmp    short CpyNxt        ; Pointer to 2nd Col
  191.  
  192. FilEnd: call    MakeBAT                 ; Create Load2TSR.BAT
  193.  
  194.         cmp     word ptr ResidF,0       ; If Resident
  195.         jnz     DisMsg                  ; Then Display Menu
  196.         mov     es,MenuENV              ; Else
  197.         mov     ah,49h                  ; Release
  198.         int     21h                     ; Environment
  199.         mov     es,MenuPSP              ; Copy DATA to Transient
  200.         mov     di,60h                  ; MenuTSRs PSP Area to
  201.         call    CpyData                 ; Initialize Resident DATA
  202.         mov     ah,9                    ; Display
  203.         mov     dx,offset TSRmenu       ; Installed
  204.         int     21h                     ; Message
  205.         mov     dx,di                   ; Calculate
  206.         mov     cl,4                    ; Paragraphs
  207.         shr     dx,cl                   ; to Remain
  208.         mov     ax,3100h                ; Resident
  209.         int     21h
  210.  
  211. DisMsg: mov     ah,0Eh                  ; Use ROM Teletype
  212.         mov     si,offset Display       ;  to Display Menu
  213. DMloop: lodsb                           ; Get and Display
  214.         int     10h                     ; Each Character
  215.         inc     al                      ; Until Reaching
  216.         jnz     DMloop                  ; 0FFh Byte
  217.         mov     ah,3                    ; Get and
  218.         xor     bx,bx                   ; Store
  219.         int     10h                     ; Input
  220.         sub     dx,0101h                ; Row and
  221.         mov     CurPos,dx               ; Column
  222.         call    GetLOAD                 ; Get Load2TSR Input
  223.         jnc     DisMsg                  ; Until RETURN to END
  224.  
  225.         call    EndBAT                  ; End the Load2TSR.BAT
  226.         mov     es,ResidF               ; Up-Date
  227.         mov     di,60h                  ; Resident
  228.         call    CpyData                 ; Data
  229. Exit:   mov     ax,ErrLvl               ; Exit to DOS
  230.         int     21h
  231. Main    EndP
  232.  
  233. IfPSPA  Proc
  234.         push    di                      ; Preserve Display Index
  235.         xor     bx,bx                   ; Zero TSR Counter
  236.         mov     si,offset MCBbuf        ; Search MCBs
  237. IP1Lp:  add     si,8                    ; If Next MCB
  238.         cmp     word ptr [si],0         ; Is Past Last
  239.         jz      NoMrk                   ; Then Exit w/CY
  240.         cmp     word ptr [si+6],-1      ; Else If NOT FMark
  241.         jne     IP1Lp                   ; Then Check Next
  242.         mov     bp,[si+2]               ; Else Get Segment
  243.         inc     bx                      ; Increment TSR #
  244.         pop     di                      ; Keep Display
  245.         push    di                      ; Index on Stack
  246.         push    si                      ; Preserve MCB Index
  247.         push    ds                      ; and Segment While
  248.         mov     ds,bp                   ; Comparing FMark
  249.         mov     si,82h                  ; Command TSRfilespec
  250.         push    di                      ; Preserve Location
  251.         mov     di,offset EVMrk+7       ; While Including
  252. DirLp:  cmpsb                           ; Directory Bytes
  253.         je      DirLp                   ; Until Dir End
  254.         cmp     byte ptr es:[di-1],0    ; If Wasn't End
  255.         pop     di                      ; {Stack Evened}
  256.         jne     Exit2                   ; Then NO Match
  257.         cmp     byte ptr [si-1],"\"     ; Else If "\"
  258.         je      CmpFN                   ; Then Disregard
  259.         dec     si                      ; Else Compare to
  260. CmpFN:  sub     di,9                    ; Current FileName
  261.  
  262. IP2Lp:  lodsb                           ; If Match
  263.         cmp     al,13                   ; to End
  264.         je      Exit2                   ; Then PSPA to Status
  265.         cmp     al,"a"                  ; Else If NOT Lower
  266.         jc      IP2Cp                   ; Case Alphabetic
  267.         cmp     al,"z"                  ; Character Byte
  268.         ja      IP2Cp                   ; Then Compare AS IS
  269.         and     al,5Fh                  ; Else If UpperCase
  270. IP2Cp:  cmp     es:[di],al              ; Byte Fails Match
  271.         jne     Exit2                   ; Then Check Next MCB
  272.         inc     di                      ; Else Check Bytes
  273.         jmp     short IP2Lp             ; Until Exit Compare
  274.  
  275. Exit2:  pop     ds                      ; Restore DS:SI
  276.         pop     si                      ; If NO Match
  277.         jne     IP1Lp                   ; Then Check Next MCB
  278.         pop     di                      ; Else Restore Status
  279.         mov     bp,[si+10]              ; Location for Next PSP
  280.         call    BP2PSPA                 ; Address in Status
  281.     push    di            ; Preserve Position
  282.     call    NBX2ASC         ; While Add Counter
  283.         pop     di                      ; Restore Display Index
  284.         ret                             ; Return NoCarry Flag
  285.  
  286. NoMrk:  pop     di                      ; Restore Display Index
  287.         stc                             ; Return Carry Flag SET
  288.         ret
  289. IfPSPA  EndP
  290.  
  291. DoFlags Proc
  292.         push    si                      ; Preserve
  293.         push    di                      ; Pointers and
  294.         push    es                      ; Segment Register
  295.         mov     bp,di                   ; Copy for Comparisons
  296.         sub     dx,di                   ; If Environment Block
  297.         jnz     DFexit                  ; Then Flag Non-Zero
  298.         mov     es,di                   ; Else Examine
  299.         mov     di,61h                  ; Identification for
  300.         mov     si,offset UsageMsg+3    ; MenuTSRs being in
  301.         mov     cx,12                   ; Residence
  302.         rep     cmpsb                   ; If NO ResID
  303.         jne     Ck4Mrk                  ; Then Check for File-Mark
  304.         mov     ResidF,bp               ; Else MenuTSRs IS Resident
  305. Ck4Mrk: mov     di,60h                  ; Check Identification for
  306.         mov     cx,9                    ; "FM3.1 TSR"
  307.         mov     si,offset MarkID        ; File-Mark ID
  308.         rep     cmpsb                   ; If NOT File-Mark
  309.         jne     ChkW30                  ; Then Check for Watch
  310.         mov     dx,-1                   ; Else Flag as File-Mark
  311.         jmp     short DFexit
  312. ChkW30: mov     di,81h                  ; If Command Area
  313.         mov     si,offset MarkID+6      ; Does NOT Contain
  314.         mov     cx,11                   ; "TSR WATCHER"
  315.         rep     cmpsb                   ; for ANY Watch
  316.         jne     ChkCVP                  ; Then Check CV MenuTSRs
  317.         mov     WatchF,bp               ; Else Store Watch PSP
  318. ChkCVP: mov     ax,es:[86h]             ; If the Command
  319.         and     ax,5F5Fh                ; Parameter does
  320.         cmp     ax,"ST"                 ; NOT have "TSRs"
  321.         jne     ChkPSP                  ; Then Check If Transient
  322.         mov     ax,es:[88h]             ; Else If "TSRs"
  323.         and     ax,5F5Fh                ; regardless
  324.         cmp     ax,"SR"                 ; of case
  325.         je      StorBP                  ; Then IS CodeView
  326. ChkPSP: cmp     MenuPSP,bp              ; Else If NOT MenuTSRs
  327.         jne     DFexit                  ; Then Leave Flag Zero
  328. StorBP: mov     dx,bp                   ; Else Flag as NOT TSR
  329.  
  330. DFexit: pop     es                      ; Restore Segment
  331.         pop     di                      ; Destination and
  332.         pop     si                      ; Source Pointers
  333.         mov     [si+bx+6],dx            ; Set MCB Flags
  334.         ret
  335. DoFlags EndP
  336.  
  337. GetDirs Proc
  338.         push    es                      ; Preserve MCB and
  339.         mov     es,di                   ; Scan Environment
  340.         xor     di,di                   ; CX bytes for
  341. TSR1st: mov     si,offset EVTSR         ; TSRdir variable
  342.         lodsb                           ; first character
  343.         repne   scasb                   ; If NOT Found
  344.         jne     InTSRv                  ; Then Input TSRdir
  345.         call    GErest                  ; Else If NOT Rest
  346.         jne     TSR1st                  ; Then Scan Until Done
  347.         jmp     short EnvMrk            ; Else Have TSRdir
  348.  
  349. InTSRv: mov     dx,offset EVTSR         ; Input TSRdir
  350.         call    InpVar                  ; Until Acceptable for
  351.         jc      InTSRv                  ; DOS Master Environment
  352.  
  353. EnvMrk: xor     di,di                   ; Scan Environment
  354.         mov     cx,EnvLen               ; Length for
  355. Mrk1st: mov     si,offset EVMrk         ; MrkDir variable
  356.         lodsb                           ; first character
  357.         repne   scasb                   ; If NOT Found
  358.         jne     InMrkV                  ; Then Input MrkDir
  359.         call    GErest                  ; Else If NOT Rest
  360.         jne     Mrk1st                  ; Then Scan Until Done
  361.         jmp     short GDexit            ; Else Have MrkDir
  362.  
  363. InMrkV: mov     dx,offset EVMrk         ; Input MrkDir
  364.         call    InpVar                  ; Until Acceptable for
  365.         jc      InMrkV                  ; Master DOS Environment
  366.  
  367. GDexit: pop     es                      ; Restore MCB
  368.         mov     di,EnvSEG               ; and Segment
  369.         ret
  370. GetDirs EndP
  371.  
  372. GErest  Proc
  373.         push    cx                      ; Preserve Counter
  374.         mov     cx,5                    ; Set Counter
  375. ERlp:   mov     bx,5                    ; Set Byte
  376.         sub     bx,cx                   ; Offset
  377.         lodsb                           ; Convert Byte to
  378.         and     al,5Fh                  ; UPPER Case and
  379.         cmp     es:[di+bx],al           ; If Bytes Match
  380.         loope   ERlp                    ; Then Check 5
  381.         jne     ERdone                  ; Else Exit NE
  382.         lodsb                           ; Match Found
  383.         cmp     es:[di+5],al            ; If "=" Sign
  384. ERdone: pop     cx                      ; If Match Found
  385.         je      Ok2Cpy                  ; Then Copy Content
  386.         pushf                           ; Else Preserve NE
  387.         xor     al,al                   ; Find End of
  388.         repne   scasb                   ; Variable and
  389.         popf                            ; Return NE Flag
  390.         ret
  391.  
  392. Ok2Cpy: add     di,6                    ; Advance Past "="
  393.         mov     cx,24                   ; Limit Length
  394.         xor     ah,ah                   ; Zero Upper AX
  395. CpyVar: mov     al,es:[di]              ; Copy
  396.         mov     [si],al                 ; Bytes
  397.         inc     si                      ; Advancing
  398.         inc     di                      ; Pointers
  399.         or      ax,ax                   ; Until Ending
  400.         loopnz  CpyVar                  ; Null or Limit
  401.         cmp     byte ptr ds:[si-2],"\"  ; If NOT "\" at End
  402.         jne     GEexit                  ; Then Environment Ok
  403.         mov     [si-2],al               ; Else Null it Out
  404.         sub     di,2                    ; Back-Up in ENV and
  405.         stosb                           ; Null-Out its "\"
  406.         mov     ah,0FFh                 ; Insure AX NOT 0
  407. AdjENV: mov     al,es:[di+1]            ; Move Environment
  408.         stosb                           ; Bytes Back one Byte
  409. GEexit: or      ax,ax                   ; Until Second of
  410.         mov     ah,al                   ; Double Null Bytes
  411.         jnz     AdjENV                  ; has been moved
  412.         ret
  413. GErest  EndP
  414.  
  415. InpVar  Proc
  416.         push    dx                      ; Preserve Name and
  417.         mov     ah,9                    ; Request to Enter
  418.         mov     dx,offset ReqVar        ; Drive:[\Path]
  419.         int     21h                     ; for the
  420.         pop     dx                      ; Directory
  421.         mov     cx,7                    ; "???dir="
  422.         mov     bx,1                    ; via Standard
  423.         mov     ah,40h                  ; Output Device
  424.         int     21h
  425.         add     dx,7                    ; Position to Input
  426.         mov     cx,25                   ; Up to 25 bytes
  427.         xor     bx,bx                   ; from Console
  428.         mov     ah,3Fh                  ; Keyboard Device
  429.         int     21h                     ; If Input Less
  430.         cmp     ax,4                    ; Than "d:"
  431.         jc      IVexit                  ; Then Error Exit
  432.         mov     bx,ax                   ; Else Locate
  433.         add     bx,dx                   ; CR and LF to
  434.         xor     ax,ax                   ; Null Out
  435.         mov     ds:[bx-2],ax
  436.         cmp     byte ptr ds:[bx-3],"\"  ; If NOT "\" Ending
  437.         jne     IV2env                  ; Then Input is Ok
  438.         mov     ds:[bx-3],al            ; Else Null it Out
  439. IV2env: xor     di,di                   ; Scan for Ending
  440.         mov     cx,EnvLen               ; Environment Nulls
  441. IVlp1:  repne   scasb                   ; If First Null is NOT
  442.         cmp     es:[di],al              ; followed by Second
  443.         jne     IVlp1                   ; Then Loop Until
  444.         mov     si,dx                   ; Double Null
  445.         mov     cx,6                    ; Replace Second
  446.         sub     si,7                    ; Null and Next
  447. IVlp2:  lodsb                           ; Five Charcters
  448.         and     al,5Fh                  ; with UPPER Case
  449.         stosb                           ; Variable Name
  450.         loop    IVlp2                   ; and then add
  451.         mov     cx,bx                   ; Variable with
  452.         sub     cx,si                   ; at least two
  453.         rep     movsb                   ; Null Bytes
  454. IVexit: ret
  455. InpVar  EndP
  456.  
  457. BP2PSPA Proc
  458.         push    ax                      ; Preserve
  459.         push    bx                      ; General
  460.         push    cx                      ; Working
  461.         push    dx                      ; Registers
  462.         mov     bx,4096                 ; Set Divide and
  463.         mov     cx,4                    ; Shift Registers
  464.  
  465. B2Plp:  xor     dx,dx                   ; Zero Extension
  466.         mov     ax,bp                   ; Get PSP Value
  467.         div     bx                      ; Calculate Digit
  468.         mov     bp,dx                   ; Store Remainder
  469.         or      al,30h                  ; If ASCII Digit
  470.         cmp     al,3Ah                  ; Is Decimal
  471.         jc      B2Padj                  ; Then ASCII is Ok
  472.         add     al,7                    ; Else HEX Convert
  473. B2Padj: push    cx                      ; Reset Shift
  474.         mov     cx,4                    ; Register and
  475.         shr     bx,cl                   ; Adjust Divisor
  476.         stosb                           ; Store PSP Digit
  477.         pop     cx                      ; Restore Counter
  478.         loop    B2Plp                   ; Loop for 4 Digits
  479.         pop     dx                      ; Restore
  480.         pop     cx                      ; General
  481.         pop     bx                      ; Working
  482.         pop     ax                      ; Registers
  483.         ret
  484. BP2PSPA EndP
  485.  
  486. NBX2ASC Proc
  487.         sub     di,17                   ; Position Pointer
  488.         push    ax                      ; Preserve
  489.         push    bx                      ; TSR # &
  490.         push    cx                      ; Working
  491.         push    dx                      ; Registers
  492.         mov     ax,bx                   ; Divide TSR # by
  493.         mov     bx,10                   ; Decimal Base
  494.         mov     cx,3                    ; Three Times
  495. NBXlp1: xor     dx,dx                   ; Clear Top
  496.         div     bx                      ; Store
  497.         push    dx                      ; Remainder
  498.         loop    NBXlp1                  ; Three
  499.         mov     cx,3                    ; Times
  500. NBXlp2: pop     ax                      ; If Result
  501.         or      ax,ax                   ; Is NOT 0
  502.         jnz     NBXdig                  ; Or If
  503.         cmp     cx,1                    ; Last Place
  504.         je      NBXdig                  ; Then Digit
  505.         sub     ax,10h                  ; Else Space
  506. NBXdig: add     ax,30h                  ; Store ASCII
  507.         stosb                           ; Byte in AL
  508.         loop    NBXlp2                  ; Until Three
  509.         pop     dx                      ; Restore
  510.         pop     cx                      ; General
  511.         pop     bx                      ; Working
  512.         pop     ax                      ; Registers
  513.     ret
  514. NBX2ASC EndP
  515.  
  516. MakeBAT Proc
  517.         mov     si,offset EVMrk+7       ; Initialize
  518.         mov     di,offset DTA           ; Filespec
  519. MBnext: lodsb                           ; with Mark
  520.         or      al,al                   ; Directory
  521.         stosb                           ; Until
  522.         jnz     MBnext                  ; Null
  523.         dec     di                      ; Add at Null
  524.         mov     si,offset FMark +6      ; File to Create
  525.         mov     cx,14                   ; "\Load2TSR.BAT"
  526.         rep     movsb                   ; ASCIIZ String
  527.         mov     ah,3Ch                  ; Create
  528.         mov     dx,offset DTA           ; BAT file
  529.         int     21h
  530.         mov     bp,ax                   ; Store Handle
  531.         mov     ah,40h                  ; Write to
  532.         mov     bx,bp                   ; Handle
  533.         mov     cx,10                   ; "Echo Off"
  534.         mov     dx,offset BatDat+7      ; plus CRLF
  535.         int     21h
  536.         ret
  537. MakeBAT EndP
  538.  
  539. GetLOAD Proc
  540.         mov     ah,2                    ; Restore
  541.         mov     dx,CurPos               ; Cursor
  542.         int     10h                     ; Position
  543.         mov     ax,0E20h                ; Space-Out
  544.         mov     cx,80h                  ; Input Area
  545. Spaces: int     10h
  546.         loop    Spaces
  547.         mov     ah,2                    ; Restore Cursor
  548.         int     10h                     ; Position for
  549.         mov     dx,offset Disk+8        ; User Input of
  550.         mov     cx,80h                  ; Up to 128 byte
  551.         mov     ah,3Fh
  552.         int     21h                     ; If NOT
  553.         mov     si,dx                   ; RETURN
  554.         cmp     word ptr ds:[si],0A0Dh  ; to END
  555.         jne     GLinit                  ; Then Check Input
  556.         stc                             ; Else Exit
  557.         jmp     GLexit                  ; With CY Flag
  558.  
  559. GLinit: mov     di,offset TSR01-44      ; Initialize and
  560.         push    si                      ; Preserve Input Pointer
  561. GLcknx: add     di,48                   ; Check TSRfile Name
  562.         mov     cx,9                    ; Through Ending Space
  563.         pop     si                      ; Keep Input Index On
  564.         push    si                      ; Stack and Preserve
  565.         push    di                      ; Display Pointer
  566. GLcpnx: cmp     byte ptr ds:[si],"a"    ; If Input Byte
  567.         jc      GLCNOk                  ; Is NOT Lower
  568.         cmp     byte ptr ds:[si],"z"    ; Case Alpha
  569.         ja      GLCNOk                  ; Then is Ok
  570.         and     byte ptr ds:[si],5Fh    ; Else UPcase
  571. GLCNOk: cmpsb                           ; If Bytes Match
  572.         loope   GLcpnx                  ; Through Space
  573.         jcxz    GLCPOk                  ; Then TSR Matches
  574.         cmp     cx,8                    ; Else If 1st Fails
  575.         je      GLnone                  ; Then Match Fails
  576.         cmp     byte ptr es:[di-1]," "  ; Else If TSRfile
  577.         je      GLCPOk                  ; Name + Space
  578.         cmp     byte ptr es:[di-1],13   ; Or End of Input
  579.         je      GLCPOk                  ; Then TSR Matches
  580.  
  581. GLnone: pop     di                      ; Else If NOT Last
  582.         cmp     di,offset TSR12+4       ; Line of 1st Col
  583.         jc      GLcknx                  ; Then Next Line
  584.         cmp     di,offset TSR24+4       ; Else If at END
  585.         jnc     GLendC                  ; Then End Checks
  586.         mov     di,offset TSR13-44      ; Else Loop to 1st
  587.         jmp     short GLcknx            ; Line and 2nd Col
  588. GLendC: pop     si                      ; At End Even Stack
  589.         mov     ax,0E07h                ; Beep for NO Match
  590.         int     10h                     ; Loop Until Input
  591.         jmp     short GetLOAD           ; RETURN to END
  592.  
  593. GLCPOk: pop     di                      ; Insure Index at
  594.         add     di,9                    ; Status Location
  595.         push    bx                      ; Preserve BX=0 and
  596.         push    bp                      ; Load2TSR Handle
  597.         call    IfPSPA                  ; If TSRfile
  598.         pop     bp                      ; Is Already
  599.         pop     bx                      ; Installed
  600.         pop     si                      ; {Stack Evened}
  601.         jnc     PastMk                  ; Then UpDate
  602.         mov     si,offset Disk          ; Else Insure
  603.         mov     cx,4                    ; That Status
  604.         push    di                      ; IS "DISK"
  605.         rep     cmpsb                   ; If "DISK"
  606.         pop     di                      ; Is NOT
  607.         push    si                      ; Matched
  608.         jne     GLendC                  ; Then Beep
  609.         pop     si                      ; Else Copy
  610.         mov     cx,4                    ; "LOAD" over
  611.         rep     movsb                   ; "DISK"
  612.         mov     ah,40h                  ; Write
  613.         mov     dx,offset FMark         ; "FMark " to
  614.         mov     cx,6                    ; Load2TSR.BAT
  615.         mov     bx,bp                   ; File Handle
  616.         int     21h
  617.         mov     dx,offset EVMrk+7       ; Add FMark
  618.         mov     di,dx                   ; Directory
  619.         mov     cx,25                   ; Path
  620.         xor     al,al                   ; Up to
  621.         repne   scasb                   ; Null
  622.         dec     di
  623.         mov     cx,di
  624.         mov     ah,40h                  ; Write
  625.         sub     cx,dx                   ; Path
  626.         int     21h
  627.         mov     dx,offset FMark+6
  628.         mov     ah,40h                  ; Write
  629.         mov     cx,1                    ; "\"
  630.         int     21h
  631.         mov     dx,offset Disk+8        ; Scan
  632.         mov     si,dx                   ; Input
  633. GLmore: lodsb                           ;  for
  634.         cmp     al," "                  ; Space
  635.         jnc     GLmore                  ; or Less
  636.         mov     ah,40h                  ; Write
  637.         mov     cx,si                   ; TSRfile
  638.         sub     cx,dx                   ; Name
  639.         int     21h
  640.         mov     dx,offset Display       ; Use CRLF to
  641.         mov     cx,2                    ; End BAT line
  642.         mov     ah,40h
  643.         int     21h
  644. PastMk: mov     dx,offset EVTSR+7       ; Scan
  645.         mov     di,dx                   ; TSRdir
  646.         mov     cx,25                   ; for
  647.         xor     al,al                   ; Null
  648.         repne   scasb                   ; Use
  649.         dec     di                      ; Null
  650.         mov     cx,di                   ; for
  651.         sub     cx,dx                   ; Length
  652.         mov     ah,40h                  ; Write to
  653.         mov     bx,bp                   ; Load2TSR.BAT
  654.         int     21h                     ; TSRdir Path
  655.         mov     dx,offset FMark+6       ; and Ending
  656.         mov     cx,1                    ; "\"
  657.         mov     ah,40h
  658.         int     21h
  659.         mov     dx,offset Disk+8        ; Add
  660.         mov     cx,80h                  ; Input
  661.         mov     di,dx                   ; Up to
  662.         mov     al,10                   ; End
  663.         repne   scasb
  664.         mov     cx,di                   ; Calculate
  665.         sub     cx,dx                   ; Length
  666.         mov     ah,40h
  667.         int     21h
  668.         mov     dx,offset BatDat        ; Add "Echo."
  669.         mov     cx,7                    ; plus CRLF
  670.         mov     ah,40h
  671.         int     21h
  672.         clc                             ; Clear Carry to Continue
  673. GLexit: ret
  674. GetLOAD EndP
  675.  
  676. EndBAT  Proc
  677.         mov     ah,40h                  ; Write to
  678.         mov     bx,bp                   ; Load2TSR.BAT
  679.         mov     cx,12                   ; "KillLOAD"
  680.         mov     dx,offset BatDat+17     ; + 2 CRLFs
  681.         int     21h
  682.         mov     ah,3Eh                  ; Close File
  683.         int     21h                     ; Load2TSR.BAT
  684.         ret
  685. EndBAT  EndP
  686.  
  687. CpyData Proc
  688.         mov     si,offset UsageMsg+3    ; Point to and
  689.         mov     cx,12                   ; Copy ID after
  690.         mov     ax,cx                   ; Storing
  691.         stosb                           ; Length of
  692.         rep     movsb                   ; "MenuTSRs 3.1"
  693.  
  694.         mov     si,offset Display       ; Add CR,LF & LF
  695.         mov     cx,3
  696.         rep     movsb
  697.         mov     si,offset MenuPSP       ; Add Data
  698.         mov     cx,8                    ; Words to
  699.         rep     movsw                   ; End @ 7Fh
  700.         ret                             ; DI=80h
  701. CpyData EndP
  702.  
  703. _TEXT   EndS
  704.         End     Main
  705.