home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / DOS_HELP / ADVMSDOS.ZIP / DUMP.ASM < prev    next >
Encoding:
Assembly Source File  |  1986-06-19  |  11.6 KB  |  351 lines

  1.         name    dump
  2.         page    55,132
  3.         title   'DUMP --- Display File Contents' 
  4.  
  5. ; DUMP --- a utility to display the contents of a file in hex
  6. ; and ASCII format.  Requires MS-DOS version 2.0 or higher.
  7. ;
  8. ; version 1.0   March 25, 1984 
  9. ; Copyright (c) 1984 by Ray Duncan
  10. ;
  11. ; Used in the form:
  12. ; A>dump path\filename.ext  [ >device ]
  13. ; (item in square brackets is optional)
  14. ;
  15. ; To assemble, link, and convert this program into 
  16. ; an EXE file, follow these steps:
  17. ;
  18. ;    C>MASM DUMP;
  19. ;     C>LINK DUMP;
  20. ;
  21.  
  22. cr      equ     0dh             ;ASCII carriage return
  23. lf      equ     0ah             ;ASCII line feed
  24. blank    equ    20h        ;ASCII space code
  25.  
  26. command equ     80h             ;buffer for command tail
  27.  
  28. blksize equ     128             ;size of input file records
  29.  
  30. output_handle equ 1             ;handle of standard output device
  31.                                 ;(can be redirected)
  32. error_handle equ 2        ;handle of standard error device
  33.                 ;(not redirectable)
  34.  
  35. cseg    segment para public 'CODE'
  36.  
  37.         assume  cs:cseg,ds:data,es:data,ss:stack
  38.  
  39.  
  40. dump    proc    far             ;entry point from MS-DOS
  41.  
  42.         push    ds              ;save DS:0000 for final
  43.         xor     ax,ax           ;return to MS-DOS, in case
  44.         push    ax        ;function 4CH can't be used.    
  45.         mov     ax,data         ;make our data segment
  46.         mov     es,ax           ;addressable via ES register.
  47.         mov     ah,30h        ;check version of MS-DOS.    
  48.         int     21h
  49.         cmp     al,2
  50.         jae     dump1           ;proceed, DOS 2.0 or greater.
  51.         mov     dx,offset msg3  ;DOS 1.x --- print error message;
  52.     mov    ax,es        ;we must use the old MS-DOS
  53.     mov    ds,ax        ;string output function since
  54.     mov    ah,9        ;handles are not available in
  55.     int    21h        ;this version of MS-DOS.
  56.     ret
  57.  
  58. dump1:  call    get_filename    ;get path and file spec. for
  59.                                 ;input file from command line tail.
  60.         mov     ax,es           ;set DS=ES for remainder
  61.         mov     ds,ax           ;of program.
  62.         jnc     dump2           ;jump, got acceptable name.
  63.         mov     dx,offset msg2  ;missing or illegal filespec,
  64.     mov    cx,msg2_length
  65.         jmp     dump9           ;print error message and exit.
  66.  
  67. dump2:  call    open_input      ;now try to open input file
  68.         jnc     dump3           ;jump,opened input ok
  69.         mov     dx,offset msg1  ;open of input file failed,
  70.     mov    cx,msg1_length
  71.         jmp     dump9           ;print error msg and exit.
  72.  
  73. dump3:  call    read_block      ;initialize input file buffer
  74.      jnc    dump4        ;jump,got a block
  75.     mov    dx,offset msg4    ;empty file,print error
  76.     mov    cx,msg4_length
  77.     jmp    dump9        ;message and exit
  78.  
  79.                                 ;file successfully opened,             
  80. dump4:                          ;now convert and display it! 
  81.         call    get_char        ;read 1 character from input.
  82.         jc      dump8           ;jump, end of file
  83.     inc    input_addr    ;update relative file position
  84.     or    bx,bx        ;is this 1st char of block?
  85.     jnz    dump5        ;no
  86.     call    print_heading
  87.  
  88. dump5:  and     bx,0fh        ;is this first byte of 16?
  89.     jnz    dump6        ;no,jump
  90.     push    ax        ;save the byte
  91.     mov    di,offset output;convert relative file addr. 
  92.     mov    ax,input_addr    ;for output string
  93.     call    conv_word 
  94.     pop    ax
  95.  
  96. dump6:                ;store ASCII version of character,
  97.                 ;if it is alphanumeric,
  98.     mov    di,offset outputb
  99.     add    di,bx        ;calculate output string address
  100.     mov    byte ptr [di],'.' ;if it is control character,
  101.     cmp    al,blank    ;just print a dot.    
  102.     jb    dump7         ;jump, not alphanumeric.
  103.     cmp    al,7eh        
  104.     ja    dump7         ;jump, not alphanumeric.
  105.     mov    [di],al        ;store ASCII character.
  106.  
  107. dump7:                ;now convert binary byte
  108.                 ;to hex  ASCII equivalent.
  109.     push    bx        ;save offset 0-15 of this byte.
  110.                 ;calc. its position in
  111.                 ;output string.
  112.     mov    di,offset outputa
  113.     add    di,bx        ;base addr + (offset*3)
  114.     add    di,bx
  115.     add    di,bx
  116.     call    conv_byte    ;convert data byte to hex 
  117.     pop    bx        ;restore byte offset
  118.     cmp    bx,0fh        ;16 bytes converted yet?
  119.     jne    dump4        ;no,get another byte
  120.     mov    dx,offset output
  121.     mov    cx,output_length
  122.     call    write_std    ;yes, print the line
  123.         jmp     dump4           ;get next char. from input file.
  124.  
  125. dump8:                          ;end of file detected,
  126.         call    close_input     ;close input file. 
  127.     mov    ax,4c00h    ;now exit to MS-DOS with
  128.     int    21h        ;return code=zero
  129.  
  130. dump9:                          ;come here to print message 
  131.                 ;on standard error device, 
  132.         call    write_error     ;and return control to MS-DOS
  133.     mov    ax,4c01h    ;with return code = 1
  134.     int    21h
  135.     
  136. dump    endp
  137.  
  138.  
  139. get_filename proc near          ;process name of input file
  140.                                 ;return Carry = 0 if successful
  141.                 ;return Carry = 1 if no filename
  142.                 ;DS:SI <- addr command line     
  143.         mov     si,offset command
  144.                                 ;ES:DI <- addr filespec buffer
  145.         mov     di,offset input_name
  146.         cld
  147.         lodsb                   ;any command line present?
  148.         or      al,al           ;return error status if not.
  149.         jz      get_filename4
  150. get_filename1:                  ;scan over leading blanks
  151.         lodsb                   ;to file name.
  152.         cmp     al,cr           ;if we hit carriage return...
  153.         je      get_filename4   ;jump, name is missing
  154.         cmp     al,20h          ;is this a blank?
  155.         jz      get_filename1   ;if so keep scanning.
  156. get_filename2:                  ;found first char of name,
  157.         stosb                   ;move last char. to output
  158.                                 ;file name buffer. 
  159.         lodsb                   ;check next character, found
  160.         cmp     al,cr           ;carriage return yet?   
  161.         je      get_filename3   ;yes,exit with success code.
  162.         cmp     al,20h          ;is this a blank?
  163.         jne     get_filename2   ;if not keep moving chars.
  164. get_filename3:                  ;exit with carry =0
  165.         clc                     ;for success flag
  166.         ret
  167. get_filename4:                  ;exit with carry =1
  168.         stc                     ;for error flag
  169.         ret
  170. get_filename endp 
  171.  
  172. open_input proc near            ;open input file
  173.                                 ;DS:DX=addr filename
  174.         mov     dx,offset input_name
  175.         mov     al,0            ;AL=0 for read only
  176.         mov     ah,3dh          ;function 3dh=open
  177.         int     21h             ;handle returned in AX,
  178.         mov     input_handle,ax ;save it for later.
  179.         ret                     ;CY is set if error
  180. open_input endp
  181.  
  182. close_input proc near           ;close input file
  183.         mov     bx,input_handle ;BX=handle
  184.         mov     ah,3eh
  185.         int     21h
  186.         ret
  187. close_input endp
  188.  
  189. get_char proc   near            ;get one character from input buffer
  190.                 ;return AL = char, BX = buffer offset
  191.                 ;return CY flag = 1 if end of file
  192.         mov     bx,input_ptr    ;is pointer at end of buffer?
  193.         cmp     bx,blksize      
  194.         jne     get_char1       ;no,jump
  195.                                 ;yes, buffer is exhausted, 
  196.     mov    input_ptr,0
  197.         call    read_block      ;new block must be read from disk.
  198.     jnc    get_char    ;got block, start routine over.
  199.     ret            ;end of file detected
  200.                 ;so return CY flag = True.
  201. get_char1:            ;get data byte into AL,
  202.         mov     al,[input_buffer+bx]
  203.         inc     input_ptr    ;bump input buffer pointer.
  204.     clc            ;return CY flag =0 since 
  205.         ret            ;not end of file.
  206. get_char endp   
  207.  
  208.  
  209. read_block proc near            ;read block of data from input file.
  210.                 ;return CY flag = 0 if read ok.
  211.                 ;       CY flag = 1 if end of file.
  212.         mov     bx,input_handle ;request read from MS-DOS.
  213.         mov     cx,blksize
  214.         mov     dx,offset input_buffer
  215.         mov     ah,3fh
  216.         int     21h
  217.                 ;initialize pointers
  218.     inc    input_block
  219.         mov     input_ptr,0 
  220.     or    ax,ax        ;was anything read in? (the OR 
  221.                 ; incidentally turns off the CY flag)
  222.     jnz    read_block1    ;yes,jump
  223.     stc            ;no,end of file so return CY=True
  224. read_block1:
  225.         ret
  226. read_block endp
  227.  
  228. write_std proc     near        ;write string to standard output.
  229.                 ;call DX = addr of output string
  230.                 ;     CX = length of string
  231.         mov     bx,output_handle;BX=handle for standard list device.
  232.         mov     ah,40h          ;function 40h=write to device.
  233.         int     21h             ;request service from DOS.
  234.         ret
  235. write_std endp
  236.  
  237. write_error proc near        ;write string to standard error device.
  238.                 ;call DX = addr of output string
  239.                 ;     CX = length of string
  240.         mov     bx,error_handle ;BX=handle for standard error device.
  241.         mov     ah,40h          ;function 40h=write to device.
  242.         int     21h             ;request service from DOS.
  243.         ret
  244. write_error endp
  245.  
  246. print_heading proc near         ;print record number and heading
  247.      push    ax        ;for a block of data
  248.      push    bx        ;first save registers     
  249.      mov    di,offset headinga
  250.      mov    ax,input_block 
  251.      call    conv_word    ;convert record number to ASCII
  252.     mov    dx,offset heading
  253.     mov    cx,heading_length
  254.     call    write_std    ;now print heading
  255.      pop    bx        ;restore registers
  256.      pop    ax
  257.         ret            ;and exit
  258. print_heading endp
  259.  
  260. conv_word proc near        ;convert 16-bit binary word 
  261.                 ; to hex ASCII
  262.                 ;call with AX=binary value
  263.                 ;          DI=addr to store string
  264.                 ;returns AX, DI, CX destroyed
  265.     push    ax
  266.     mov    al,ah
  267.     call    conv_byte    ;convert upper byte    
  268.     pop    ax
  269.     call    conv_byte    ;convert lower byte
  270.     ret
  271. conv_word endp
  272.  
  273. conv_byte proc    near          ;convert binary byte to hex ASCII
  274.                                 ;call with AL=binary value
  275.                                 ;          DI=addr to store string
  276.                                 ;returns   AX, DI, CX modified 
  277.  
  278.     sub    ah,ah        ;clear upper byte
  279.     mov    cl,16
  280.     div    cl        ;divide binary data by 16
  281.     call    ascii        ;the quotient becomes the first
  282.     stosb            ;ASCII character
  283.     mov    al,ah
  284.     call    ascii        ;the remainder becomes the
  285.     stosb            ;second ASCII character
  286.     ret
  287. conv_byte endp
  288.  
  289. ascii   proc     near        ;convert value 0-0FH in AL 
  290.         add     al,'0'        ;into a "hex ASCII" character
  291.         cmp     al,'9'
  292.         jle     ascii2        ;jump if in range 0-9,
  293.         add     al,'A'-'9'-1    ;offset it to range A-F,
  294. ascii2:    ret            ;return ASCII char. in AL.
  295. ascii    endp
  296.  
  297. cseg    ends
  298.  
  299.  
  300. data    segment para public 'DATA'
  301.  
  302. input_name      db      64 dup (0)      ;buffer for input filespec
  303.  
  304. input_handle    dw      0               ;token from PCDOS for input file.
  305.  
  306. input_ptr       dw      0               ;pointer to input deblocking buffer
  307.  
  308. input_addr      dw      -1              ;relative address in file 
  309. input_block     dw      0               ;current 128 byte block number
  310.  
  311. output        db    'nnnn',blank,blank
  312. outputa        db    16 dup ('00',blank)
  313.         db    blank
  314. outputb         db    '0123456789ABCDEF',cr,lf 
  315. output_length    equ    $-output
  316.  
  317. heading        db    cr,lf,'Record',blank
  318. headinga    db    'nnnn',blank,blank,cr,lf
  319.         db    7 dup (blank)
  320.         db    '0  1  2  3  4  5  6  7  '
  321.         db    '8  9  A  B  C  D  E  F',cr,lf
  322. heading_length  equ    $-heading
  323.  
  324. input_buffer    db      blksize dup (?) ;deblocking buffer for input file
  325.  
  326. msg1            db      cr,lf
  327.                 db      'Cannot find input file.'
  328.                 db      cr,lf
  329. msg1_length    equ    $-msg1
  330.  
  331. msg2            db      cr,lf
  332.                 db      'Missing file name.'
  333.                 db      cr,lf
  334. msg2_length    equ    $-msg2
  335.  
  336. msg3            db      cr,lf
  337.                 db      'Requires MS-DOS version 2 or greater.'
  338.                 db      cr,lf,'$'
  339.  
  340. msg4        db    cr,lf,'Empty file.',cr,lf
  341. msg4_length    equ    $-msg4
  342.  
  343. data    ends    
  344.  
  345.  
  346. stack   segment para stack 'STACK'
  347.         db      64 dup (?)
  348. stack   ends
  349.  
  350.         end     dump
  351.