home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pcmagazi / 1990 / 16 / install.asm < prev    next >
Assembly Source File  |  1990-06-28  |  20KB  |  716 lines

  1. ; INSTALL.ASM
  2. ; (c) 1989, 1990 Ashok P. Nadkarni
  3. ;
  4. ; This code is the installation code for CMDEDIT. This file must be
  5. ; linked last !
  6.  
  7.     INCLUDE common.inc
  8.     INCLUDE ascii.inc
  9.     INCLUDE dos.inc
  10.     INCLUDE general.inc
  11.  
  12.     PUBLIC    install_begin
  13.     PUBLIC    install
  14.     PUBLIC    file_error
  15.     PUBLIC    abort_install
  16.     PUBLIC    dirstk_error
  17.     PUBLIC    process_args
  18.  
  19. CSEG    SEGMENT    PARA PUBLIC 'CODE'
  20.     EXTRN    getargs:PROC
  21.     EXTRN    cmdlen:BYTE
  22.     EXTRN    default_imode:BYTE
  23.     EXTRN    auto_recall:BYTE
  24.     EXTRN    pgm_name:BYTE
  25.     EXTRN    silent:BYTE
  26.     EXTRN    macrosize:WORD
  27.     EXTRN    macro_ignore_char:BYTE
  28.     EXTRN    symsize:WORD
  29.     EXTRN    dossize:WORD
  30.     EXTRN    dirsize:WORD
  31.     EXTRN    mfilename:BYTE
  32.     EXTRN    mfile_seen:BYTE
  33.     EXTRN    prev_isr1b:WORD
  34.     EXTRN    enable_dircmds:BYTE
  35.     EXTRN    dos_version_major:BYTE
  36.     EXTRN    dos_version_minor:BYTE
  37.     EXTRN    old_int21vec:WORD
  38.     EXTRN    cmdedit:PROC
  39.     EXTRN    our_break_handler:PROC
  40.     EXTRN    init_over:PROC
  41.     EXTRN    cmdedit_isr:PROC
  42.  
  43. DGROUP    GROUP    CSEG
  44.  
  45.  
  46.     ASSUME    CS:DGROUP,DS:DGROUP,ES:DGROUP,SS:DGROUP
  47.  
  48. ; install_begin MUST be start of installation code.
  49. install_begin    LABEL BYTE
  50. msg_nomem    db    '* Insufficient Memory - Reduce buffer sizes *',CR,LF,DOLLAR
  51. option_error db '* Unknown or illegal options *',CR,LF,DOLLAR
  52. file_error   db '* Error processing command file *',CR,LF,DOLLAR
  53. dirstk_error db '* Error processing directory stack commands *',CR,LF,DOLLAR
  54. inv_dosver   db '* Unsupported DOS version. *',CR,LF,DOLLAR
  55. msg_dup         db '* CMDEDIT already installed in memory. *',CR,LF,DOLLAR
  56. options_dup  db '* Only options /g /i /r /p may be specified. *',CR,LF,DOLLAR
  57. msg_notdup   db '* No copy of CMDEDIT found in memory. *',CR,LF,DOLLAR
  58. msg_unload   db '* Unable to unload CMDEDIT.        *',CR,LF
  59.          db '* Uninstall TSRs in reverse order.    *',CR,LF,DOLLAR
  60. msg_memerr   db '* DOS memory allocation error! *',CR,LF,BEL
  61.          db '* Recommend you reboot!        *',CR,LF,BEL,DOLLAR
  62. msg_uninstalled db '* CMDEDIT uninstalled successfully *',CR,LF,DOLLAR
  63. msg_omode db '* Default overwrite mode enabled. *',CR,LF,DOLLAR
  64. msg_imode db '* Default insert mode enabled. *',CR,LF,DOLLAR
  65. msg_enable_autorecall db '* CMDEDIT autorecall enabled. *',CR,LF,DOLLAR
  66. msg_disable_autorecall db '* CMDEDIT autorecall disabled. *',CR,LF,DOLLAR
  67. msg_enable_bell db '* CMDEDIT error bell enabled. *',CR,LF,DOLLAR
  68. msg_disable_bell db '* CMDEDIT error bell disabled. *',CR,LF,DOLLAR
  69. msg_ignore_char db '* CMDEDIT ignore character changed. *',CR,LF,DOLLAR
  70.  
  71. cmdedit_seg  dw    0                ;Segment of the first copy
  72. ;                         of CMDEDIT loaded into memory.
  73.  
  74. argflags     db    0    ;Used to remember what args have been seen.
  75. dosarg        equ    1
  76. applarg        equ    2
  77. filearg        equ    4
  78. dirarg        equ    8
  79. macroarg    equ    16
  80. symarg        equ    32
  81. uninstall_arg    equ    64
  82. ignore_arg    equ    128
  83.  
  84. argument_buffer db    LINEBUF_SIZE DUP (?)
  85.  
  86. ;    This location is jumped to when the program is run from the DOS
  87. ;    command line. The program parses the input line, takes
  88. ;    appropriate actions, initializes buffers etc. and then TSR's
  89. ;    after taking over interrupt 21h. The memory taken up by the ISEG
  90. ;    segment will then be used for various data buffers since this
  91. ;    code is no longer needed.
  92. install proc    near
  93.     cld            ;Entire program assumes direction flag will
  94. ;                 be cleared
  95.  
  96.     ASSUME CS:DGROUP,DS:DGROUP,ES:DGROUP,SS:DGROUP
  97.     @DispStr pgm_name        ;Display program name
  98.  
  99. ; Make sure we are running DOS 2.x or higher
  100.     call    near ptr get_dosversion
  101.     cmp    dos_version_major,1        ;DOS 1.x ?
  102.     jne    @install_1
  103.     @DispStr inv_dosver
  104.     mov    ax,-1
  105.     jmp    abort_install            ;V1.x not supported.
  106.  
  107. @install_1:
  108. ; Locate the segment of the first copy of CMDEDIT in memory so that
  109. ; we can tell if this is a second copy.
  110.     call    near ptr locate_cmdedit
  111.     mov    cmdedit_seg,ax            ;Remember it
  112.  
  113. @install_5:
  114.     mov    si,offset cmdlen ;
  115.     lodsb            ;SI == line in PSP, AL == line length
  116.     mov    cl,al
  117.     xor    ch,ch        ;CX = line length
  118.     xor    ax,ax        ;Function = get argument count
  119.     push    cx        ;Save line length
  120.     call     near ptr getargs ;AX := # arguments in command line
  121.     pop    cx        ;Restore line length
  122.     mov    di,ax        ; DI == number of arguments
  123.     inc    di        ;Prime for loop
  124. @install_10:
  125.     dec    di        ;Any more arguments ?
  126.     jz    @install_20    ;No
  127.     mov    bx,offset DGROUP:argument_buffer
  128.     mov    dx,SIZE argument_buffer
  129.     mov    ax,di        ;Argument number
  130.     push    cx        ;save line length
  131.     call     near ptr getargs ;Get argument into argument_buffer
  132. ;                  (no chance of buffer being too short)
  133.     call     near ptr process_args ;Process the argument
  134.     pop    cx        ;Restore line length
  135.     jmp    short @install_10 ;loop back to process remaining args
  136.  
  137.  
  138. @install_20:
  139. ; OK now we have done all necessary parsing without errors. Now first check
  140. ; if the uninstall option was specified.
  141.     test    argflags,uninstall_arg
  142.     je    @install_21        ;Nope
  143.  
  144. ; We have to unload a previously installed copy of CMDEDIT. See if it is
  145. ; really there.
  146.     mov    ax,ds            ;Are we the only copy of CMDEDIT ?
  147.     cmp    ax,cmdedit_seg
  148.     je    @install_20_a        ;There is no other copy
  149.     jmp    uninstall
  150.  
  151. @install_20_a:
  152.     @DispStr msg_notdup        ;Indicate no copy to uninstall
  153.     mov    ax,-1
  154.     jmp    abort_install        ;Exit 
  155.  
  156. @install_21:
  157. ; No uninstall option specified. Now check if this is the only copy of
  158. ; CMDEDIT.
  159.     mov    ax,ds
  160.     cmp    ax,cmdedit_seg
  161.     je    @install_21_a        ;We are the only copy. Proceed with
  162. ;                     installation 
  163.     jmp    change_installed_options ;Else go change installed options.
  164.  
  165. @install_21_a:
  166. ; At this point all the arguments have been parsed. Now check
  167. ; that the sum total of the various buffer sizes does not exceed
  168. ; segment limits. Also check for mandatory minimum sizes.
  169. ; Finally, transfer control to the resident portion which will
  170. ; relocate buffers to overlay the installation code.
  171.  
  172.     mov    ax,OFFSET DGROUP:install_begin
  173.                     ;add starting address where buffers
  174.                     ; will begin
  175.     add    ax,STACK_SIZE
  176.     jnc    @install_23
  177.     jmp    @install_125
  178. @install_23:
  179.     cmp    macrosize,MACROSIZE_MIN
  180.     jnb    @install_22
  181.     mov    macrosize,MACROSIZE_MIN ;Ensure min buffer sizes
  182. @install_22:
  183.     add    ax,macrosize
  184.     jc    @install_125
  185.     cmp    symsize,SYMSIZE_MIN
  186.     jnb    @install_24
  187.     mov    symsize,SYMSIZE_MIN ;Ensure min buffer sizes
  188. @install_24:
  189.     add    ax,symsize
  190.     jc    @install_125
  191.     cmp    dossize,DOSSIZE_MIN
  192.     jnb    @install_26
  193.     mov    dossize,DOSSIZE_MIN ;Ensure min buffer sizes
  194. @install_26:
  195.     add    ax,dossize
  196.     jc    @install_125
  197.     cmp    dirsize,DIRSIZE_MIN
  198.     jnb    @install_30
  199.     mov    dirsize,DIRSIZE_MIN ;Ensure min buffer sizes
  200. @install_30:
  201.     add    ax,dirsize
  202.     jc    @install_125
  203. ;Enough memory, so keep resident. Install our Ctrl-Break handler.
  204.     push    es            ;Save ES
  205.     mov    ah,35h
  206.     mov    al,1bh            ;Ctrl-Break Interrupt
  207.     int    21h            ;Get current handler address
  208.     mov    CS:prev_isr1b,bx    ;Offset of previous handler
  209.     mov    CS:prev_isr1b+2,es    ;Segment of previous handler
  210.     pop    es            ;Restore es
  211.     mov    dx,offset CS:our_break_handler
  212.     push    ds            ;Save DS
  213.     mov    ax,cs
  214.     mov    ds,ax            ;DS:DX->our break handler
  215.     mov    al,1bh
  216.     mov    ah,25h            ;Set up our break handler
  217.     int    21h
  218.     pop    ds            ;Restore DS
  219. ;
  220.     jmp    near ptr init_over
  221.  
  222.  
  223.  
  224. @install_125:
  225.     @DispStr msg_nomem
  226.     mov    ax,-1
  227.     jmp    abort_install
  228.  
  229. install endp
  230.  
  231.  
  232.  
  233.  
  234. ;+
  235. ; FUNCTION : process_args
  236. ;
  237. ;    Processes the argument pointed to by BX. AX contains length 
  238. ;    of argument. If a previously seen argument is repeated, it is
  239. ;    ignored (ie. the old value is kept). Note that the argument is
  240. ;    assumed not to contain any delimiters (like space or tab).
  241. ;
  242. ;    Options start with either a '-' or '/'. Any associated value must
  243. ;    follow immediately after without any intervening space/tab.
  244. ;        /f    Macro file to be read.
  245. ;        /d    DOS history buffer size
  246. ;        /a    Application history buffer size (only if
  247. ;            separate histories maintained) (OUTDATED)
  248. ;        /m    Macro buffer size
  249. ;        /b    symbol buffer size
  250. ;        /s    Directory Stack size
  251. ;        /r    Auto recall mode
  252. ;        /i    Insert mode default
  253. ;        /g    Silent mode
  254. ;        /p    macro ignore character
  255. ;        /e    Enable dir commands all the time (OUTDATED)
  256. ;        /u    Uninstall CMDEDIT
  257. ;
  258. ;    Invalid options result in program abortion. If an option is not
  259. ;    followed by a value, the default value for the option is assumed.
  260. ;
  261. ;    Note that this is NOT a general purpose getopt type routine.
  262. ;
  263. ; Parameters:
  264. ;    BX    = Pointer to argument
  265. ;    AX    = Number of characters in argument
  266. ;
  267. ; Returns:
  268. ;    Nothing.
  269. ;    Various globals may be set according to the specified argument.
  270. ; Register(s) BX (call to aton),CX  are destroyed.
  271. ;-
  272. process_args proc near
  273.     @save    si,di
  274.     test    argflags,uninstall_arg
  275.     jne    @process_args_5    ;If /U specified, no other arg is allowed
  276.  
  277.     xchg    ax,cx        ;CX = character count
  278.     sub    cx,2        ;Delete switch char and option letter
  279.     jb    @process_args_5    ;Error in option specification
  280.                 ;  if num chars less than 2
  281.     mov    si,bx        ;SI = arg buffer address
  282.     lodsb            ;AL = first character
  283.     cmp    al,'/'        ;Should be either '/'
  284.     je    @process_args_10 ;
  285.     cmp    al,'-'        ; or '-'
  286.     jne    short @process_args_5    ;Else error
  287.  
  288. @process_args_10:            ;Saw a valid switch char
  289.     lodsb                ;AL = option letter
  290.     or    al,32            ;Lowercase (non alphabetic will be
  291.                     ; ignored anyway)
  292.     cmp    al,'u'            ;Uninstall option ?
  293.     jne    @process_args_11_a    ;No
  294.     or    cx,cx            ;Ok if no more chars in arg
  295.     jne    short @process_args_5    ;Else error
  296.  
  297. @process_args_11:
  298.     or    argflags,uninstall_arg    ;Indicate /U seen
  299.     jmp    @process_args_50    ;Return
  300.  
  301. @process_args_11_a:
  302.     cmp    al,'i'            ;insert mode option ?
  303.     jne    @process_args_14    ;No
  304.     jcxz    @process_args_12    ;Ok if no more chars in arg
  305. @process_args_5:
  306. ; Error processing
  307.     @DispStr option_error
  308.     mov    ax,-1
  309.     jmp    abort_install
  310. @process_args_12:
  311.     mov    default_imode,1        ;Change default insrt mode
  312.     jmp    @process_args_50    ;Return
  313. @process_args_14:
  314.     cmp    al,'g'            ;silent mode option ?
  315.     jne    @process_args_15    ;No
  316.     jcxz    @process_args_14_a    ;Ok if no more chars in arg
  317.     jmp    short @process_args_5    ;Else error
  318. @process_args_14_a:
  319.     mov    silent,1        ;Silent mode
  320.     jmp    @process_args_50    ;Return
  321. @process_args_15:
  322.     cmp    al,'r'            ;auto-recall option ?
  323.     jne    @process_args_18    ;No
  324.     jcxz    @process_args_16    ;Ok if no more chars in arg
  325.     jmp    short @process_args_5    ;Else error
  326. @process_args_16:
  327.     mov    auto_recall,1        ;Set auto-recall mode
  328.     jmp    @process_args_50    ;Return
  329. @process_args_18:
  330.     cmp    al,'e'            ;Enable dir commands option?
  331.     jne    @process_args_18_b    ;No
  332.     jcxz    @process_args_18_a    ;OK if no more chars
  333.     jmp    short @process_args_5    ;Else error
  334. @process_args_18_a:
  335.     mov    enable_dircmds,1    ;enable directory commands
  336.     jmp    @process_args_50    ;Return
  337. @process_args_18_b:
  338.     cmp    al,'p'            ;ignore character option
  339.     jne    @process_args_19
  340.     cmp    cx,1            ;Should be only one more char
  341.     jne    @process_args_5        ;Error
  342.     lodsb
  343.     or    argflags,ignore_arg    ;Indicate that an ignore char set
  344.     mov    macro_ignore_char,al
  345.     jmp    @process_args_50    ;Return
  346. @process_args_19:
  347.     cmp    al,'f'            ;Is it the macro file option ?
  348.     jne    @process_args_20
  349.     test    argflags,filearg    ;Already seen file argument ?
  350.     je    @process_args_19_a    ;No, then update
  351.     jmp    @process_args_50    ;Yes, then don't update
  352. @process_args_19_a:
  353.     or    argflags,filearg    ;Remember we've seen this option
  354.     jcxz    @process_args_50    ;If 0 count, no file to be read
  355.     cmp    cx,63            ;Max path length must be < 64
  356.     ja    @process_args_5        ;Error
  357.     mov    di,offset mfilename    ;Temp storage for filename
  358.     rep    movsb            ;Copy file name
  359.     mov    byte ptr [di],0        ;Terminate with a NULL char
  360.     mov    mfile_seen,1        ;Indicate that init file specified
  361.     jmp    short @process_args_50
  362. @process_args_20:
  363.     push    ax        ;Save the option letter
  364.     xchg    ax,cx        ;AX = num of char
  365.     call    near ptr aton    ;All other options are numeric values
  366.     jnc    @process_args_22 ;No Errors
  367.     jmp    @process_args_5            ;Error
  368. @process_args_22:
  369. ;AX contains numeric value
  370.     xchg    ax,cx        ;CX = numeric value
  371.     pop    ax        ;Restore option letter
  372.  
  373.     cmp    al,'d'        ;Is it the dos history size option ?
  374.     jne    @process_args_25
  375.     test    argflags,dosarg ;Already seen argument ?
  376.     jne    @process_args_50 ;Yes, then don't update
  377.     or    argflags,dosarg ;Remember we've seen this option
  378.     mov    dossize,cx
  379.     jmp    short @process_args_50
  380. @process_args_25:
  381.     cmp    al,'m'        ;Is it the macro buf size option ?
  382.     jne    @process_args_35
  383.     test    argflags,macroarg ;Already seen argument ?
  384.     jne    @process_args_50 ;Yes, then don't update
  385.     or    argflags,macroarg ;Remember we've seen this option
  386.     mov    macrosize,cx
  387.     jmp    short @process_args_50
  388.  
  389. @process_args_35:
  390.     cmp    al,'b'        ;Is it the symbol buf size option ?
  391.     jne    @process_args_40
  392.     test    argflags,symarg ;Already seen argument ?
  393.     jne    @process_args_50 ;Yes, then don't update
  394.     or    argflags,symarg ;Remember we've seen this option
  395.     mov    symsize,cx
  396.     jmp    short @process_args_50
  397.  
  398. @process_args_40:
  399.     cmp    al,'s'        ;Is it the dir stack option ?
  400.     je    @process_args_55 ;Yes
  401.     jmp    @process_args_5  ;Invalid arg
  402. @process_args_55:
  403.     test    argflags,dirarg ;Already seen argument ?
  404.     jne    @process_args_50 ;Yes, then don't update
  405.     or    argflags,dirarg ;Remember we've seen this option
  406.     mov    dirsize,cx
  407.     
  408. @process_args_50:
  409.  
  410.     @restore
  411.     ret
  412. process_args endp
  413.  
  414.  
  415. ;+
  416. ; FUNCTION : aton
  417. ;
  418. ;    Returns the positive integer value of an ASCII string. The value
  419. ;    must be between 0 and 65535. If length of string is 0, then a 0
  420. ;    value is returned with no error flags.
  421. ;
  422. ; Parameters:
  423. ;    SI    := address of first character in string
  424. ;    AX    := count of characters
  425. ;
  426. ; Returns:
  427. ;    AX = 16 bit result if no errors.
  428. ;    CF = 1 if error (magnitude too large, invalid character etc.)
  429. ;         0 if no errors.
  430. ; Register(s) CX,DX  are destroyed.
  431. ;-
  432. aton    proc    near
  433.     @save    si,di
  434.     xor    di,di        ;Result
  435.     xchg    ax,cx        ;CX <- num of chars
  436.     jcxz    @aton_99    ;No chars, result = 0 (CF is also 0)
  437.     cmp    cx,6        ;Shouldn't be more'n 5 chars
  438.     cmc            ;CF=1 if error
  439.     jb    @aton_99    ;Error exit
  440. @aton_10:
  441.     lodsb            ;al = char
  442.     sub    al,'0'        ;Is ASCII value < '0'
  443.     jb    @aton_99
  444.     mov    dx,9        ;Comparison with 9, NOT '9'
  445.     cmp    dl,al
  446.     jb    @aton_99    ;Not valid char
  447.     xor    ah,ah
  448.     inc    dx        ;DX = 10 (multiplier)
  449.     xchg    ax,di        ;ax = result so far
  450.     mul    dx        ;Multiply by 10
  451.     jb    @aton_99    ;Overflow
  452.     add    ax,di        ;Add new character
  453.     jb    @aton_99    ;Overflow
  454.     xchg    ax,di        ;Remember new result in di
  455.     loop    @aton_10    ;Go onto next char
  456. @aton_99:
  457.     xchg    ax,di
  458.     @restore
  459.     ret
  460. aton    endp
  461.  
  462.  
  463. ;+
  464. ; FUNCTION : get_dosversion
  465. ;
  466. ;
  467. ; Stores DOS major and minor versions in dos_version_major and
  468. ; dos_version_minor.
  469. ;-
  470. get_dosversion proc near
  471.     mov    ah,30h
  472.     int    21h
  473.     mov    dos_version_major,al
  474.     mov    dos_version_minor,ah
  475.     ret
  476. get_dosversion endp
  477.  
  478.  
  479.  
  480.  
  481. ;+
  482. ; FUNCTION : abort_install
  483. ;
  484. ;    Called to abort program before installation. Exits to DOS.
  485. ;
  486. ; Parameters:
  487. ;    AL    = Exit code
  488. ;
  489. ; Returns:
  490. ;    Nothing.
  491. ;
  492. ; Register(s) destroyed:
  493. ;    N/A
  494. ;-
  495. abort_install proc near
  496.     @Exit
  497. abort_install endp
  498.  
  499.  
  500.  
  501. ;+
  502. ; FUNCTION : locate_cmdedit
  503. ;
  504. ;    Called to locate the first copy of CMDEDIT loaded into memory. This
  505. ;    is not foolproof in that if CMDEDIT is loaded into high memory
  506. ;    using one of the memory managers like QEMM, it will not be found.
  507. ;
  508. ; Parameters:
  509. ;    None.
  510. ;
  511. ; Returns:
  512. ;    AX - segment of first copy of CMDEDIT in memory.
  513. ;
  514. ; Register(s) destroyed:
  515. ;    <TBA>
  516. ;-
  517. locate_cmdedit proc near
  518.     @save    si,di,es
  519.     mov    di,offset DGROUP:cmdedit    ;SI and DI will used for
  520.     mov    si,di                ;comparisons
  521.     xor    ax,ax                ;AX will track segments
  522.  
  523. @locate_cmdedit_5:
  524.     mov    es,ax
  525.     push    si                ;Save offsets that are
  526. ;                         compared 
  527.     mov    cx,32                ;Count to be matched
  528.     rep    cmpsb
  529.     pop    si                ;Restore offsets that are
  530. ;                         compared 
  531.     je    @locate_cmdedit_50        ;Matched
  532.     mov    di,si
  533.     inc    ax
  534.     jmp    short @locate_cmdedit_5        ;Try next segment
  535.  
  536. @locate_cmdedit_50:
  537.  
  538.     @restore
  539.     ret
  540. locate_cmdedit endp
  541.  
  542.  
  543. ;+
  544. ; FUNCTION : uninstall
  545. ;
  546. ;    Called to uninstall a previously loaded copy of CMDEDIT.
  547. ;    The routine does not return. It exits CMDEDIT.
  548. ;
  549. ; Parameters:
  550. ;    None.
  551. ;
  552. ; Returns:
  553. ;    None.
  554. ;
  555. ; Register(s) destroyed:
  556. ;    <TBA>
  557. ;-
  558. uninstall proc near
  559. ; Free up the memory occupied by the previous loaded copy of CMDEDIT.
  560. ; First give back the all interrupts that were taken over.
  561.  
  562. ; Make sure no one else has taken over the 1b break handler since we
  563. ; took it over.
  564.     mov    ax,351bh        ;Retrieve current 1b handler
  565.     int    21h
  566.     cmp    bx,offset our_break_handler ;Is the offset the ours ?
  567.     je    @uninstall_20        ;Yes
  568. @uninstall_10:
  569. ; Someone else's taken over the interrupt. Display message and exit.
  570.     @DispStr msg_unload
  571.     mov    ax,-1
  572.     jmp    abort_install
  573. @uninstall_20:
  574.     mov    ax,es            ;Now compare segment
  575.     cmp    ax,cmdedit_seg        ;Is it what we expect?
  576.     jne    @uninstall_10        ;No, display error
  577.  
  578. ; Now check the int 21h handler.
  579.     mov    ax,3521h        ;Retrieve current 1b handler
  580.     int    21h
  581.     cmp    bx,offset cmdedit_isr    ;Is the offset the ours ?
  582.     jne    @uninstall_10        ;No, error
  583.     mov    ax,es            ;Now compare segment
  584.     cmp    ax,cmdedit_seg        ;Is it what we expect?
  585.     jne    @uninstall_10        ;No, display error
  586.  
  587. ; OK, now restore both interrupts
  588.     mov    es,cmdedit_seg        ;ES<-segment of loaded CMDEDIT
  589.     mov    dx,es:prev_isr1b    ;DS:DX->original 1b handler
  590.     mov    ds,es:prev_isr1b+2
  591.     mov    ax,251bh        ;Return int 1b
  592.     int    21h
  593.  
  594.     mov    dx,es:old_int21vec    ;DS:DX->original int 21h handler
  595.     mov    ds,es:old_int21vec+2
  596.     mov    ax,2521h        ;Return int 21
  597.     int    21h
  598.  
  599.     push    cs
  600.     pop    ds            ;Restore DS
  601. ;
  602. ; Finally, return the block of memory taken up by the previous CMDEDIT copy.
  603.     mov    ah,49h            ;Release block function, ES->segment
  604.     int    21h            ;Free the block
  605.     jnc    @uninstall_90        ;No errors
  606.     @DispStr msg_memerr        ;Memory allocation error !
  607.     mov    ax,-1
  608.     jmp    abort_install
  609.  
  610. @uninstall_90:
  611.     @DispStr msg_uninstalled
  612.     xor    ax,ax
  613.  
  614.     @Exit    0            ;Exit to DOS
  615.  
  616. uninstall endp
  617.  
  618.  
  619. ;+
  620. ; FUNCTION : change_installed_options
  621. ;
  622. ;    Called to change settings on a previously installed copy of
  623. ;    CMDEDIT. The function exits to DOS.
  624. ;
  625. ;    This function allows the following options to be toggled or
  626. ;    changed:
  627. ;        /r - toggles autorecall mode
  628. ;        /i - toggles insert mode
  629. ;        /g - toggles silent mode
  630. ;        /p - sets a new ignore character
  631. ;
  632. ;    If any other option is specified, error message is displayed.
  633. ;    
  634. ; Parameters:
  635. ;    None.
  636. ;
  637. ; Returns:
  638. ;    Nothing.
  639. ;
  640. ; Register(s) destroyed:
  641. ;    <TBA>
  642. ;-
  643.  
  644. change_installed_options proc near
  645.     @DispStr msg_dup
  646.     mov    al,argflags
  647.     and    al,NOT ignore_arg
  648.     je    @change_installed_options_10
  649. ; Unallowed options specified.
  650.     @DispStr options_dup
  651.     mov    ax,-1
  652.     jmp    abort_install
  653.  
  654. @change_installed_options_10:
  655.     @DispCh LF
  656. ; Change the options specified.
  657.     mov    es,cmdedit_seg        ;ES->segment of previously loaded
  658. ;                     CMDEDIT 
  659. ; First toggle the insert mode option. If /i specified, default_imode will
  660. ; be 1, else 0. Thus just xor it with the memory resident copy to toggle
  661. ; default mode.
  662.     mov    al,es:default_imode
  663.     xor    al,default_imode    
  664.     mov    es:default_imode,al    ;Toggle memory resident option
  665.     or    al,al
  666.     je    @change_installed_options_15
  667.     @DispStr msg_imode
  668.     jmp    short @change_installed_options_20
  669. @change_installed_options_15:
  670.     @DispStr msg_omode
  671.  
  672. @change_installed_options_20:
  673.     mov    al,es:auto_recall
  674.     xor    al,auto_recall
  675.     mov    es:auto_recall,al    ;Toggle memory resident option
  676.     or    al,al
  677.     jne    @change_installed_options_25
  678.     @DispStr msg_disable_autorecall
  679.     jmp    short @change_installed_options_30
  680. @change_installed_options_25:
  681.     @DispStr msg_enable_autorecall
  682.  
  683. @change_installed_options_30:
  684. ; And now for silent mode
  685.     mov    al,es:silent
  686.     xor    al,silent
  687.     mov    es:silent,al    ;Toggle memory resident option
  688.     or    al,al
  689.     je    @change_installed_options_35
  690.     @DispStr msg_disable_bell
  691.     jmp    short @change_installed_options_40
  692. @change_installed_options_35:
  693.     @DispStr msg_enable_bell
  694.  
  695. @change_installed_options_40:
  696.  
  697. ; Finally change the ignore character if one was specified.
  698.     test    argflags,ignore_arg
  699.     je    @change_installed_options_90 ;None specified
  700. ; Change to the new macro ignore char
  701.     mov    al,macro_ignore_char
  702.     mov    es:macro_ignore_char,al
  703.     @DispStr msg_ignore_char
  704.  
  705. @change_installed_options_90:
  706. ; All done
  707.     @Exit    0
  708.  
  709. change_installed_options endp
  710.  
  711.  
  712.  
  713.  
  714. CSEG    ENDS
  715.  
  716.     END