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