home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / FLOPPIES / VHARD101.ZIP / VHCACHE.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-07-23  |  16.9 KB  |  678 lines

  1.  
  2.     title    Manage the VHARD FAT cache
  3.     subttl    Prologue
  4.     page    60,132
  5.  
  6. comment {
  7.  
  8. ******************************************************************************
  9.  
  10. File VHCACHE.ASM
  11.  
  12. Author:
  13.     Aaron L. Brenner
  14.  
  15.     BIX mail address albrenner
  16.     GEnie address A.BRENNER
  17.  
  18.     This program is hereby released to the public domain.
  19.  
  20. Purpose:
  21.     Provide a command-driven interface to the VHARD FAT/root dir cache.
  22.  
  23. Command syntax:
  24.     VHCACHE [? | ON | OFF | MANUAL | AUTO | FLUSH]
  25.  
  26. Parameters:
  27.     ? or INFO    Display information about the cache.
  28.     ON        Enable the cache.
  29.     OFF        Disable and remove the cache.
  30.     MANUAL        Disable auto-flush.
  31.     AUTO        Enable auto-flush.
  32.     FLUSH        Write the cache to disk.
  33.  
  34.     If no parameters, a brief usage message is displayed.
  35.  
  36. ERRORLEVEL returned:
  37.     0        The requested operation was performed successfully.
  38.     1        An error was reported by the driver.
  39.     2        Command syntax error.
  40.     3        VHARD.SYS not installed.
  41.     4        Invalid DOS version
  42.     5        Insufficient free memory
  43.  
  44. Notes:
  45.     All commands (including "?") require that VHARD.SYS be installed.
  46.  
  47. Revision history:
  48. 1.00    07/20/90    ALB    Created.
  49.  
  50. ******************************************************************************
  51.  
  52. endcomment {
  53.  
  54.     subttl    Included files
  55.     page
  56.  
  57.     include    dd_defs.inc
  58.     include    vhard.inc
  59.  
  60.     subttl    Program stack and data
  61.     page
  62.  
  63. vhcache_stack    segment    stack
  64.  
  65.     dw    128 dup (0)
  66.  
  67. vhcache_stack    ends
  68.  
  69.  
  70. vhcache_data    segment
  71.  
  72. assume    ds:vhcache_data
  73.  
  74. ax_value    dw    4c00h
  75. dx_value    dw    0
  76.  
  77. vhctl_handle    dw    0
  78. vhctl_name    db    'VHARDCTL',0
  79.  
  80. vhard_drive    db    0ffh        ; Drive assigned (FF = unavailable)
  81. vhard_ver    dw    0        ; BCD version of driver
  82. vhard_BPB    DOS_BPB <>        ; BPB for the driver (we ignore it)
  83.  
  84. cache_flags    db    0        ; Flags for the cache if installed
  85. cache_addr    dw    0, 0        ; Address of current cache
  86.  
  87. cmd_block    VH_CMD <>
  88.  
  89. cmd_keyword    db    8 dup (0)    ; The keyword on the command line
  90.  
  91. vhversion    db    'VHARD version is $'
  92. vhdrive_is    db    'VHARD is using drive letter $'
  93. cached_at    db    'Currently installed cache is at $'
  94. needs_flushing    db    'Cache needs to be FLUSHed', 13, 10, '$'
  95. auto_enabled    db    'AUTOflush is enabled', 13, 10, '$'
  96.  
  97. ;
  98. ; Error messages
  99. ;
  100. no_share    db    'SHARE.EXE must be run before AUTOflush can be'
  101.         db    ' enabled.', 13, 10, '$'
  102. bad_dos_ver    db    'Invalid DOS version for AUTOflush.', 13, 10, '$'
  103. no_memory    db    'Not enough memory', 13, 10, '$'
  104. no_cache    db    'The cache is not yet installed', 13, 10, '$'
  105. unk_err        db    'unknown error$'
  106. em1        db    'drive not read$'
  107. em2        db    'seek error$'
  108. em3        db    'general failure$'
  109. em4        db    'CRC error$'
  110. em5        db    'DMA boundary error$'
  111. em6        db    'DMA overrun$'
  112. em7        db    'sector not found$'
  113. em8        db    'diskette is write-protected$'
  114. em9        db    'address mark not found$'
  115. em10        db    'unknown BIOS command$'
  116. em11        db    'unknown VHARD command$'
  117. em12        db    'cache already installed$'
  118. em13        db    'cache not installed$'
  119. em14        db    'cache must be flushed$'
  120.  
  121. err_prefix    db    'Error: $'
  122. crlf_str    db    13, 10, '$'
  123.  
  124. error_messages    dw    unk_err
  125.         dw    em1
  126.         dw    em2
  127.         dw    em3
  128.         dw    em4
  129.         dw    em5
  130.         dw    em6
  131.         dw    em7
  132.         dw    em8
  133.         dw    em9
  134.         dw    em10
  135.         dw    em11
  136.         dw    em12
  137.         dw    em13
  138.         dw    em14
  139.  
  140.  
  141. ;
  142. ; Keywords we recognize
  143. ;
  144. kw1        db    1,'?'
  145. kw11        db    4,'INFO'
  146. kw2        db    2,'ON'
  147. kw3        db    3,'OFF'
  148. kw4        db    6,'MANUAL'
  149. kw5        db    4,'AUTO'
  150. kw6        db    5,'FLUSH'
  151.  
  152. keywords    dw    kw1, kw_info
  153.         dw    kw11, kw_info
  154.         dw    kw2, kw_on
  155.         dw    kw3, kw_off
  156.         dw    kw4, kw_manual
  157.         dw    kw5, kw_auto
  158.         dw    kw6, kw_flush
  159.         dw    0
  160.  
  161. usage_msg    db    'VHCACHE v1.00 - Public Domain Software', 13, 10
  162.         db    13, 10, 'Usage: VHPREP [? | ON | OFF | MANUAL | AUTO'
  163.         db    ' | FLUSH]', 13, 10
  164.         db    13, 10, '? or INFO     Display information on the cache'
  165.         db    13, 10, 'ON            Enable the cache'
  166.         db    13, 10, 'OFF           Disable and remove the cache'
  167.         db    13, 10, 'MANUAL        Disable auto-flush'
  168.         db    13, 10, 'AUTO          Enable auto-flush'
  169.         db    13, 10, 'FLUSH         Write the cache to disk'
  170.         db    13, 10, '$'
  171.  
  172. bad_kw        db    'Unknown keyword: "$'
  173. bad_kw2        db    '".', 13, 10, '$'
  174. no_driver    db    'VHARD.SYS must be installed', 13, 10, '$'
  175.  
  176. vhcache_data    ends
  177.  
  178.  
  179.     subttl    Start of program code
  180.     page    
  181.  
  182. vhcache_code    segment
  183.  
  184. assume    cs:vhcache_code, ds:nothing, es:nothing, ss:vhcache_stack
  185.  
  186.  
  187. start    proc
  188.  
  189.     call    initialize        ; Do program initialization
  190.  
  191. assume    ds:vhcache_data
  192.  
  193.     call    do_command        ; Do the command they want
  194.     mov    ax,ax_value        ;
  195.     mov    dx,dx_value        ;
  196.     int    21h            ;
  197.  
  198. start    endp
  199.  
  200.  
  201. ;*****************************************************************************
  202. ;
  203. ; Perform once-only program initialization.
  204. ;
  205. ;*****************************************************************************
  206. initialize    proc    near
  207.  
  208.     mov    ax,vhcache_data        ; Get our data segment
  209.     mov    es,ax            ;
  210.  
  211. assume    es:vhcache_data
  212.  
  213.     mov    si,81h            ; Point to the command tail
  214.     cld                ; Make sure of direction
  215. init_l1:
  216.     lodsb                ; Get a character
  217.     cmp    al,' '            ; Is it a blank?
  218.     je    init_l1            ; Yep - ignore it
  219.     cmp    al,9            ; Tab?
  220.     je    init_l1            ; Yes - ignore it
  221.     cmp    al,0dh            ; End of the line?
  222.     jne    init_l2            ; No - copy the keyword
  223.     push    es            ; Set DS aright
  224.     pop    ds            ;
  225.  
  226. assume    ds:vhcache_data
  227.  
  228.     mov    dx,offset usage_msg    ; Display the usage message
  229.     mov    ah,9            ;
  230.     int    21h            ;
  231.     mov    ax,4c02h        ; Pretend it's an error
  232.     int    21h            ; Exit to DOS
  233. init_l2:
  234.  
  235. assume    ds:nothing
  236.  
  237.     dec    si            ; Point back to where we stopped
  238.     mov    di,offset cmd_keyword[1]; Point to where we're copying to
  239.     mov    cx,6            ; Max we want to copy
  240. init_l3:
  241.     lodsb                ; Get the next byte
  242.     cmp    al,' '            ; Done with the command?
  243.     je    init_l5            ; Yes - stop copying
  244.     cmp    al,9            ; Done with it?
  245.     je    init_l5            ; Yes - stop copying
  246.     cmp    al,0dh            ; End of the line?
  247.     je    init_l5            ; Yes - stop copying
  248.     jcxz    init_l3            ; If the name buffer's full, ignore
  249.     cmp    al,'a'            ; Is it lower case?
  250.     jb    init_l4            ; No - use it
  251.     cmp    al,'z'            ; Is it?
  252.     ja    init_l4            ; Nope - use it
  253.     xor    al,20h            ; Make it upper case
  254. init_l4:
  255.     stosb                ; Put it in the name buffer
  256.     inc    cmd_keyword[0]        ; Count this character
  257.     dec    cx            ; Both ways
  258.     jmp    short init_l3        ; Loop back for more
  259. init_l5:
  260.     sub    al,al            ; Terminate it, too
  261.     stosb                ;
  262.     push    es            ; Swap segments so we can release our
  263.     push    ds            ;  environment
  264.     pop    es            ;
  265.     pop    ds            ;
  266.  
  267. assume    ds:vhcache_data, es:nothing
  268.  
  269.     mov    es,es:[2ch]        ; Get our environment segment
  270.     mov    ah,49h            ; Fn to release memory
  271.     int    21h            ;
  272.     push    ds            ; Lastly, set ES to our data seg
  273.     pop    es            ;
  274.  
  275. assume    es:vhcache_data
  276.  
  277.     mov    dx,offset vhctl_name    ; Try to get to the VHARDCTL device
  278.     mov    ax,3c02h        ;
  279.     int    21h            ;
  280.     jnc    init_l6            ; If we could, make sure it's a device
  281. init_err:
  282.     mov    dx,offset no_driver    ; Complain that the driver's missing
  283.     mov    ah,9            ;
  284.     int    21h            ;
  285.     mov    ax,4c03h        ; Exit with appropriate code
  286.     int    21h            ;
  287. init_l6:
  288.     mov    bx,ax            ; Get the handle for it
  289.     mov    vhctl_handle,ax        ; Save it for later use, too
  290.     mov    ax,4400h        ; Get info on the handle
  291.     int    21h            ;
  292.     test    dl,80h            ; Is this a device?
  293.     jz    init_err        ; No - just a file, so complain
  294.     mov    cmd_block.VC_cmd_code,CMD_GETDATA; Get driver info
  295.     mov    word ptr cmd_block.VC_buffer[0],offset vhard_drive
  296.     mov    word ptr cmd_block.VC_buffer[2],ds
  297.     mov    dx,offset cmd_block    ; Write it out to the driver
  298.     mov    cx,size VH_CMD        ;
  299.     mov    ax,4403h        ;
  300.     int    21h            ;
  301.     ret                ; Return to Main
  302.  
  303. initialize    endp
  304.  
  305.  
  306. ;*****************************************************************************
  307. ;
  308. ; Perform the command specified by cmd_keyword.
  309. ;
  310. ;*****************************************************************************
  311. do_command    proc    near
  312.  
  313.     sub    bx,bx            ; Start at the base of the table
  314.     mov    cx,bx            ;
  315. docm_l1:
  316.     mov    di,keywords[bx]        ; Pick up a keyword pointer
  317.     or    di,di            ; Hit the end of the table?
  318.     jnz    docm_l2            ; No - see if they match
  319.     mov    dx,offset bad_kw    ; Report an unknown keyword
  320.     mov    ah,9            ;
  321.     int    21h            ;
  322.     mov    dx,offset cmd_keyword[1]; Display the errant keyword
  323.     mov    cl,cmd_keyword[0]    ;
  324.     sub    ch,ch            ;
  325.     mov    bx,1            ;
  326.     mov    ah,40h            ;
  327.     int    21h            ;
  328.     mov    dx,offset bad_kw2    ; Finish out the message
  329.     mov    ah,9            ;
  330.     int    21h            ;
  331.     mov    ax,4c02h        ; Exit with error code
  332.     int    21h            ;
  333. docm_l2:
  334.     mov    si,offset cmd_keyword    ; Point to the keyword they entered
  335.     mov    cl,[si]            ; Get the length of it
  336.     inc    cl            ; Allow for length byte
  337.     rep    cmpsb            ; Is this the one they entered?
  338.     je    docm_l3            ; Yep - call the routine
  339.     add    bx,4            ; Point to next table entry
  340.     jmp    short docm_l1        ; Loop back
  341. docm_l3:
  342.     call    keywords[2][bx]        ; Call the appropriate routine
  343.     ret                ; Return to Main
  344.  
  345. do_command    endp
  346.  
  347.     subttl    Command keyword handlers
  348.     page
  349.  
  350. ;*****************************************************************************
  351. ;
  352. ; Command keyword handlers
  353. ;
  354. ;*****************************************************************************
  355.  
  356.  
  357. ;*****************************************************************************
  358. ;
  359. ; Handle the "?" or "INFO" keyword.
  360. ; Display information about the cache.
  361. ;
  362. ;*****************************************************************************
  363. kw_info        proc    near
  364.  
  365.     mov    al,5            ; Get the cache info
  366.     mov    word ptr cmd_block.VC_buffer[0],offset cache_flags
  367.     mov    word ptr cmd_block.VC_buffer[2],ds
  368.     call    call_driver        ; Get the info
  369.     test    cache_flags,CACHE_INSTALLED    ; Is the cache installed?
  370.     jnz    kwin_l1            ; Yep - display its info
  371.     mov    dx,offset no_cache    ; Tell 'em it ain't there
  372.     mov    ah,9            ;
  373.     int    21h            ;
  374.     jmp    kwin_exit        ; Exit now
  375. kwin_l1:
  376.     mov    dx,offset vhversion    ; Say what version of VHARD we have
  377.     mov    ah,9            ;
  378.     int    21h            ;
  379.     mov    ax,vhard_ver        ; Get the version word
  380.     push    ax            ; Save it
  381.     mov    al,ah            ; Display major version
  382.     call    disp_byte        ;
  383.     mov    dl,'.'            ;
  384.     mov    ah,6            ;
  385.     int    21h            ;
  386.     pop    ax            ; Display minor version
  387.     call    disp_byte        ;
  388.     mov    dx,offset crlf_str    ; End the line
  389.     mov    ah,9            ;
  390.     int    21h            ;
  391.     inc    vhard_drive        ; Do we have the drive assigned
  392.     jz    kwin_l2            ; Nope - don't know what drive
  393.     mov    dx,offset vhdrive_is    ; Tell 'em the drive letter
  394.     mov    ah,9            ;
  395.     int    21h            ;
  396.     mov    dl,vhard_drive        ;
  397.     add    dl,'@'            ;
  398.     mov    ah,6            ;
  399.     int    21h            ;
  400.     mov    dl,':'            ;
  401.     mov    ah,6            ;
  402.     int    21h            ;
  403.     mov    dx,offset crlf_str    ; End this line
  404.     mov    ah,9            ;
  405.     int    21h            ;
  406. kwin_l2:
  407.     mov    dx,offset cached_at    ; Tell 'em where the cache is now
  408.     mov    ah,9            ;
  409.     int    21h            ;
  410.     mov    ax,cache_addr[2]    ;
  411.     call    disp_word        ;
  412.     mov    dl,':'            ;
  413.     mov    ah,6            ;
  414.     int    21h            ;
  415.     mov    ax,cache_addr[0]    ;
  416.     call    disp_word        ;
  417.     mov    dx,offset crlf_str    ; End the line
  418.     mov    ah,9            ;
  419.     int    21h            ;
  420.     test    cache_flags,CACHE_DIRTY    ; Is the cache dirty?
  421.     jz    kwin_l3            ; No - just exit
  422.     mov    dx,offset needs_flushing; Tell 'em it needs to be flushed
  423.     mov    ah,9            ;
  424.     int    21h            ;
  425. kwin_l3:
  426.     test    cache_flags,CACHE_AUTO    ; AUTOflush enabled?
  427.     jz    kwin_exit        ; Nope - exit now
  428.     mov    dx,offset auto_enabled    ; Tell 'em about it
  429.     mov    ah,9            ;
  430.     int    21h            ;
  431. kwin_exit:
  432.     ret                ; Return to caller
  433.  
  434. kw_info        endp
  435.  
  436.  
  437. ;*****************************************************************************
  438. ;
  439. ; Output the value in AX as 4 hex digits
  440. ;
  441. ;*****************************************************************************
  442. disp_word    proc    near
  443.  
  444.     push    ax            ; Save the value
  445.     mov    al,ah            ; Do the high byte first
  446.     call    disp_byte        ;
  447.     pop    ax            ; Now, the low byte
  448. disp_byte:
  449.     push    ax            ; Save the low nybble
  450.     mov    cl,4            ; Move the high nybble down
  451.     shr    al,cl            ;
  452.     call    disp_nybble        ; Display the nybble
  453.     pop    ax            ; Get low nybble back
  454. disp_nybble:
  455.     and    al,0fh            ; Keep the low nybble
  456.     add    al,90h            ; Convert to ASCII hex digit
  457.     daa                ;
  458.     adc    al,40h            ;
  459.     daa                ;
  460.     mov    dl,al            ; Send it to the display
  461.     mov    ah,6            ;
  462.     int    21h            ;
  463.     ret                ; Return to caller
  464.  
  465. disp_word    endp
  466.  
  467.  
  468. ;*****************************************************************************
  469. ;
  470. ; Handle the "ON" keyword
  471. ;
  472. ;*****************************************************************************
  473. kw_on        proc    near
  474.  
  475.     mov    ah,51h            ; Get our PSP
  476.     int    21h            ;
  477.     mov    es,bx            ;
  478.     mov    bx,768            ; Need 12K at least
  479.     mov    ah,4ah            ;
  480.     int    21h            ;
  481.     jnc    kwon_l1            ; If we got it, install
  482.     mov    dx,offset no_memory    ; Report insufficient memory
  483.     mov    ah,9            ;
  484.     int    21h            ;
  485.     mov    byte ptr ax_value[0],5    ; Exit code
  486.     jmp    short kwon_exit        ; Exit now
  487. kwon_l1:
  488.     mov    word ptr cmd_block.VC_buffer[0],0    ; Set cache ptr
  489.     mov    word ptr cmd_block.VC_buffer[2],es    ;  to PSP:0
  490.     mov    al,1            ; Enable the cache
  491.     call    call_driver        ;
  492.     jnc    kwon_l2            ; If we did, continue
  493.     call    report_error        ; Report the error
  494.     jmp    short kwon_exit        ; Exit now
  495. kwon_l2:
  496.     mov    byte ptr ax_value[1],31h; Change exit fn to TSR exit
  497.     mov    dx_value,768        ; Set DX to # of paragraphs needed
  498.     mov    ah,30h            ; Get our DOS version
  499.     int    21h            ;
  500.     cmp    al,3            ; At least 3.x?
  501.     jb    kwon_exit        ; Nope - no auto-flush available
  502.     mov    ax,1000h        ; See if SHARE is installed
  503.     int    2fh            ;
  504.     or    al,al            ; Is it?
  505.     jz    kwon_exit        ; Nope - no auto-flush
  506.     mov    al,4            ; Enable cache auto-flush
  507.     call    call_driver        ;
  508. kwon_exit:
  509.     ret                ; Return to caller
  510.  
  511. kw_on        endp
  512.  
  513.  
  514. ;*****************************************************************************
  515. ;
  516. ; Handle the "OFF" keyword.
  517. ;
  518. ;*****************************************************************************
  519. kw_off        proc    near
  520.  
  521.     mov    al,0            ; Disable the cache
  522.     call    call_driver        ;
  523.     jnc    kwof_l1            ; If no error, release the memory
  524.     call    report_error        ; Report the error
  525.     jmp    short kwof_exit        ; Exit now
  526. kwof_l1:
  527. ;
  528. ; VHARDCTL set our VC_buffer to point to the existing cache
  529. ;
  530.     mov    es,word ptr cmd_block.VC_buffer[2]    ; Get segment to free
  531.     mov    ah,49h            ; Function to release memory
  532.     int    21h            ; Get rid of the memory
  533. kwof_exit:
  534.     ret                ; Return to caller
  535.  
  536. kw_off        endp
  537.  
  538.  
  539. ;*****************************************************************************
  540. ;
  541. ; Handle the "MANUAL" keyword
  542. ;
  543. ;*****************************************************************************
  544. kw_manual    proc    near
  545.  
  546.     mov    al,3            ; Disable auto-flush
  547.     call    call_driver        ;
  548.     jnc    kwmn_exit        ; Exit if no error
  549.     call    report_error        ; Report the error
  550. kwmn_exit:
  551.     ret                ; Return to caller
  552.  
  553. kw_manual    endp
  554.  
  555.  
  556. ;*****************************************************************************
  557. ;
  558. ; Handle the "AUTO" keyword
  559. ;
  560. ;*****************************************************************************
  561. kw_auto        proc    near
  562.  
  563.     mov    ah,30h            ; Get DOS version
  564.     int    21h            ;
  565.     cmp    al,3            ; Is it at least 3.x?
  566.     jb    kwau_err1        ; Nope - can't do autoflush
  567.     mov    ax,1000h        ; See if SHARE is installed
  568.     int    2fh            ;
  569.     cmp    al,0            ; Is it?
  570.     jz    kwau_err2        ; Nope - report error
  571.     mov    al,4            ; Enable auto-flush
  572.     call    call_driver        ;
  573.     jnc    kwau_exit        ; Exit if it went
  574.     call    report_error        ; Report an error
  575. kwau_exit:
  576.     ret                ; Return to caller
  577. ;
  578. kwau_err1:
  579.     mov    dx,offset bad_dos_ver    ;
  580.     jmp    short kwau_err3        ;
  581. kwau_err2:
  582.     mov    dx,offset no_share    ;
  583. kwau_err3:
  584.     mov    ah,9            ; Display the error message
  585.     int    21h            ;
  586.     mov    ax,4c04h        ; Exit with appropriate error code
  587.     int    21h            ;
  588.  
  589. kw_auto        endp
  590.  
  591.  
  592. ;*****************************************************************************
  593. ;
  594. ; Handle the "FLUSH" keyword
  595. ;
  596. ;*****************************************************************************
  597. kw_flush    proc    near
  598.  
  599.     mov    al,2            ; Send the "Flush Cache" command
  600.     call    call_driver        ;
  601.     jnc    kwfl_exit        ; Exit if it went
  602.     mov    byte ptr ax_value[0],1    ; Set exit code
  603.     call    report_error        ; Report the error
  604. kwfl_exit:
  605.     ret                ; Return to caller
  606.  
  607. kw_flush    endp
  608.  
  609.  
  610. ;*****************************************************************************
  611. ;
  612. ; Call VHARDCTL.
  613. ;
  614. ; Call with command code in AL.
  615. ;
  616. ; Returns with CF = 1 if VC_status <> STS_OK
  617. ;
  618. ;*****************************************************************************
  619. call_driver    proc    near
  620.  
  621.     mov    cmd_block.VC_cmd_code,CMD_CACHE    ; It's a cache command
  622.     mov    cmd_block.VC_track,al        ; Set the subcommand
  623.     mov    cmd_block.VC_status,STS_OK    ; Init to "OK" status
  624.     mov    ax,4403h        ; IOCTL write function
  625.     mov    dx,offset cmd_block    ; Point to the data to write
  626.     mov    cx,size VH_CMD        ; Number of bytes to write
  627.     mov    bx,vhctl_handle        ; Handle to write to
  628.     int    21h            ; Do it
  629.     cmp    cmd_block.VC_status,STS_OK    ; Did it fly?
  630.     je    clld_ok            ; Yes - return CF=0
  631.     stc                ; Return error flag
  632.     jmp    short clld_exit        ; Exit now
  633. clld_ok:
  634.     clc                ; No error
  635. clld_exit:
  636.     ret                ; Return to caller
  637.  
  638. call_driver    endp
  639.  
  640.  
  641. ;*****************************************************************************
  642. ;
  643. ; Common error-reporting routine
  644. ;
  645. ;*****************************************************************************
  646. report_error    proc    near
  647.  
  648. assume    ds:vhcache_data
  649.  
  650.     mov    bl,cmd_block.VC_status    ; Get the return status
  651.     cmp    bl,STS_BAD_ERROR    ; See if it was an unknown error
  652.     jne    rpte_l1            ; No - point to proper error message
  653.     mov    si,offset unk_err    ; Point to "Unknown error" message
  654.     jmp    short rpte_l2        ; Continue
  655. rpte_l1:
  656.     sub    bh,bh            ; Make the error code an offset
  657.     shl    bx,1            ;
  658.     mov    si,error_messages[bx]    ; Point to the error message
  659. rpte_l2:
  660.     mov    dx,offset err_prefix    ;
  661.     mov    ah,9            ;
  662.     int    21h            ;
  663.     mov    dx,si            ;
  664.     mov    ah,9            ;
  665.     int    21h            ;
  666.     mov    dx,offset crlf_str    ;
  667.     mov    ah,9            ;
  668.     int    21h            ;
  669.     mov    byte ptr ax_value[0],1    ; Set exit code
  670.     ret                ; Return to caller
  671.  
  672. report_error    endp
  673.  
  674.  
  675. vhcache_code    ends
  676.  
  677.     end    start
  678.