home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / Dloads / 100UTILI / MASM.ZIP / COUNT.ASM next >
Assembly Source File  |  1985-10-16  |  6KB  |  117 lines

  1. dosint      MACRO  function            ;; Call the DOS interrupt 
  2.             mov    ah,function         ;; Put function number in AH 
  3.             int    21h
  4.             ENDM
  5.  
  6. error       MACRO  errnum              ;; Display error and exit
  7.             mov    dx,OFFSET err&errnum;; Load address of error message
  8.             dosint 09h                 ;; Display string function
  9.             mov    al,errnum           ;; Exit with return code of errnum
  10.             dosint 4Ch                 ;; Quit 
  11.             ENDM
  12.  
  13. PUBLIC      prompt,namebuf,fname,buffer,err1,err2,count,new_flag
  14. PUBLIC      get_file,open_file,ok,buff_read,done,conv_hex,rotate
  15. PUBLIC      quit,word_c,next_char,new_word,old_word,out_word,get_out
  16.  
  17. stack       SEGMENT word stack 'STACK'
  18.             DB     100h DUP (?)
  19. stack       ENDS
  20.  
  21. data        SEGMENT word public 'DATA'
  22. prompt      DB     'Enter file name: $'
  23. namebuf     DB     15h,?               ; Maximum length of file name 
  24. fname       DB     15h DUP(?)          ;   is 15h (21d)
  25. buffer      DB     800h DUP(?)         ; Buffer size is 800h (2048d) 
  26. err1        DB     'Can''t access file',0Dh,0Ah,'$'
  27. err2        DB     'I/O error',0Dh,0Ah,'$'
  28. count       DW     0                   ; Initialize word count to 0
  29. new_flag    DB     1                   ; Initialize new word to true (1)
  30. data        ENDS
  31.  
  32. code        SEGMENT byte public 'CODE'
  33.             ASSUME cs:code,ds:data
  34.  
  35. start:      mov    ax,data
  36.             mov    ds,ax               ; Load data segment address
  37.  
  38.             mov    dx,OFFSET prompt    ; Load address of prompt string
  39.             dosint 09h                 ; Display it
  40. get_file:   mov    dx,OFFSET namebuf   ; Load address for file name buffer 
  41.             dosint 0Ah                 ; Get file name string
  42.             mov    si,dx               ; Set SI to start of file name buffer
  43.             mov    bl,BYTE PTR [si+1]  ; Put the number of bytes read in BL
  44.             mov    BYTE PTR [si+bx+2],0; Put 0 at end to make ASCIIZ string 
  45.                                        ;   (0 overrides CR from prompt)
  46.             mov    dl,0Ah              ; Load linefeed character
  47.             dosint 02h                 ; Print it  
  48.  
  49. open_file:  mov    dx,OFFSET fname     ; Load offset of ASCIIZ string 
  50.             xor    al,al               ; Set code 0 - open for reading
  51.             dosint 3Dh                 ; Try to open the file
  52.             jnc    ok                  ; If opened, then process file 
  53. access:     error  1                   ;   else error macro
  54.  
  55. ok:         mov    bx,ax               ; Move file handle to BX
  56.             mov    dx,OFFSET buffer    ; Give address to dump file contents
  57. io_loop:    mov    cx,800h             ; Set buffer size 
  58.             dosint 3Fh                 ; Read a buffer of data from file
  59. buff_read:  jc     io_err              ; If there's a read error, then quit
  60.             cmp    ax,0                ;   else see if we read anything
  61.             je     done                ; If not, we're done
  62.             call   word_c              ;   else count what we read 
  63.             jmp    SHORT io_loop       ; Do it again
  64. io_err:     error  2                   ; Error macro
  65.  
  66. done:       dosint 3Eh                 ; Close (file handle already in BX)
  67.  
  68.             mov    bx,count            ; Put count in BX for processing 
  69. conv_hex:   mov    cl,4                ; Load number of bits to rotate 
  70.             mov    ch,4                ; Load count for digits
  71. rotate:     rol    bx,cl               ; Rotate left digit to right
  72.             mov    dl,bl               ; Move to DL for processing 
  73.             and    dl,0Fh              ; Mask off left digit
  74.             add    dl,30h              ; Convert to ASCII digit 
  75.             cmp    dh,3Ah              ; Is it greater than 9?
  76.             jl     show                ; If not, display character
  77.             add    dl,07h              ;   else convert hex letter
  78. show:       dosint 02h                 ; Display character function
  79.             dec    ch                  ; Decrement the digit count
  80.             jnz    rotate              ; If count isn't zero, do it again
  81.  
  82. quit:       xor    al,al               ;   else set 0 for return code
  83.             dosint 4Ch                 ; Return to DOS function 
  84.  
  85. word_c      PROC   NEAR                ; Procedure to count words in buffer
  86.             push   bx                  ; Save BX - it has file handle
  87.             mov    si,OFFSET buffer-1  ; Load address one byte before buffer 
  88.             mov    bx,0                ; Set BX to 0 for word count 
  89.             mov    cx,ax               ; Put number of characters read in CX
  90.             mov    ah,new_flag         ; Set new word flag (AH) 
  91.  
  92. next_char:  inc    si                  ; Bump index (adjust on first pass)
  93.             mov    al,[si]             ; Get next character 
  94.             cmp    al,20h              ; Compare to space 
  95.             jle    out_word            ; If less, we're not in a word
  96.             cmp    ah,1                ;   else is new word flag TRUE?
  97.             je     new_word            ; If flag is TRUE, it's a new word
  98.             jmp    old_word            ;   else it's an old word 
  99.  
  100. new_word:   inc    bx                  ; Bump word count 
  101.             xor    ah,ah               ; Set new word flag to FALSE (0)
  102. old_word:   loop   next_char           ; Get next character
  103.             jmp    get_out             ; Fall through at end of buffer
  104.  
  105. out_word:   mov    ah,1                ; Set new word flag to true (1)
  106.             loop   next_char           ; Get next character
  107.  
  108. get_out:    add    count,bx            ; Add buffer count to variable 
  109.             mov    new_flag,ah         ; Save current flag status
  110.             pop    bx                  ; Restore file handle
  111.             ret
  112. word_c      ENDP
  113.  
  114. code        ENDS
  115.             END    start
  116.  
  117.