TITLE PARSE.ASM - WORD COUNT PROCEDURE
NAME PARSE
PAGE 77,132
;
; RETURNS CHAR COUNT, WORD AND SENTENCE COUNT
; COUNT OF ASCII FILES COMPILED INTO READING LEVEL INDEX
;
CSECT    SEGMENT PARA PUBLIC 'CODE'
         ASSUME    CS:CSECT,DS:CSECT,SS:NOTHING,ES:NOTHING
         ORG       100H
ENTRY:   JMP       START
;
; SKIP SMALL DATA SEGMENT]
;
CHAR_COUNT DW      0
CHAR_CT_CARRY DW   0
LINE_COUNT    DW   0
LINE_CT_CARRY DW   0
DISPLAY_FLAG  DB   0
fsize 	     dw	0	;total bytes...
fsize_cy      dw	0	;carry?
started	db	0	;<> 0 when data read...
;
maxpage	equ	66	;lines per page for defaults
alpha_string  db   ' printable characters',13,10,'$'
file_size     db	' bytes in file',13,10,'$'
word_string   db   ' words',13,10,'$'
line_string   db   ' lines',13,10,'$'
page_string   db   ' pages @ 66 Ln/Pg',13,10,'$'
carry_64k     db   '65536+$'
;
source   db        13,10,'CP file unreachable,RC=255',13,10,'$'
eofmsg   db        'EOF reached.',13,10,'$'
nodata	db	'Warning: File is empty',13,10,'$'
ENDMSG   DB        13,10,'COMMAND COMPLETE',13,10,'$'
errmsg   db        13,10,'CP File read failure',13,10
         DB        'COMMAND PROCESSING ABEND,RC=2',13,10,'$'
begmsg   db        'Execution begins ...',13,10,'$'
;
;
; BEFORE THE FILE CAN BE PARSED, THE COMMAND LINE HAS TO BE
; PARSED.  THEN THE FILE WILL BE OPENED AND READ TO MAIN STORAGE
;
START:
         MOV       DI,80H              ;POINT TO PARMS
         MOV       BL,[DI]             ;THE NUMBER OF CHARS
         XOR       BH,BH               ;ZERO TOP HALF
         MOV       BYTE PTR DS:[BX+DI+1],0
NEXT_BYTE:
         INC       DI                  ;POINT TO NEXT BYTE
         CMP       BYTE PTR DS:[DI],32 ;A SPACE DELIMITER?
         JZ        NEXT_BYTE           ;YES - SKIP DELIMITERS
         MOV       DX,DI
         MOV       AX,3D00H            ;OPEN THE FILE...
         INT       21H                 ;VIA CP
         JC        EXIT                ;ERRORS DURING OPEN
         PUSH      AX                  ;SAVE FILE HANDLE
         MOV       DX,OFFSET BEGMSG
         CALL      DISPLAY_TEXT        ;WRITE THE START MSG...
         POP       AX                  ;RECOVER...
         PUSH      AX                  ;IF OK, RECOVER THE FILEHANDLE
READ:    POP       BX                  ;INTO THE RIGHT REGISTER
         PUSH      BX
         MOV       DX,OFFSET BUFFER    ;POINT TO DTA
         MOV       CX,64000            ;~64K BYTES IN BUFFER ZONE
         MOV       AH,3FH              ;READ FROM FILE
         INT       21H                 ;WITH CP
         JC        CLOSE_FILE          ;IF FAILURE, STOP WITH CP
         CMP       AX,0                ;EOF REACHED?
         JNZ       PARSE               ;IF NOT, PARSE NEXT BATCH
GO_DISPLAY:
         MOV       DX,OFFSET EOFMSG    ;END REACHED
         CALL      DISPLAY_TEXT        ;WRITE THE MESSAGE
         CMP       FSIZE,1             ;ONLY THE EOF MARK?
         JA        DATA                ;NO - WRITE THE SUMMARY
         MOV       DX,OFFSET NODATA
         CALL      DISPLAY_TEXT
         JMP       CLOSE_FILE
DATA:
         CALL      DISPLAY             ;WRITE THE SUMMARY WITH CP
CLOSE_FILE:
         JNC       OK                  ;JUST CONTINUE
         MOV       DX,OFFSET ERRMSG    ;FILE READ ERROR
         CALL      DISPLAY_TEXT        ;WRITE AND STOP
OK:
         POP       BX                  ;FIXUP STACK
         MOV       AH,3EH              ;AND CLOSE FILE
         INT       21H                 ;CALL CP
         JC        NOT_OK
         MOV       DX,OFFSET ENDMSG
         CALL      DISPLAY_TEXT        ;END MESSAGE
         CLC                           ;CLEAR CARRY AFTER MESSAGE...
NOT_OK:  INT       20H                 ;CP KILLS PROCESS...
EXIT:
         JNC       OK2                 ;
         MOV       DX,OFFSET SOURCE
         CALL      DISPLAY_TEXT
OK2:                                   ;MESSAGE IS WRITTEN...
         INT       20H                 ;CP TERMINATION
;
; EACH BYTE OF THE FILE WILL BE EXAMINED AND THE APPROPRIATE COUNTER
; WILL BE INCREMENTED (WORD, SENTENCE TOO) LONG WORDS WILL BE COUNTED
; WHEN 8 CHARS OR MORE
;
PARSE:   MOV       CX,AX               ;SET COUNTER TO BYTES READ
         MOV       SI,OFFSET BUFFER
         CLD
GET_CHAR:
         ADD       FSIZE,1             ;
         ADC       FSIZE_CY,0
         LODSB
         AND       AL,7FH              ;STRIP WS HI - BIT IF THERE
         CMP       AL,32               ;PRINTABLE?
         JB        DELIMITER           ;IF YES, NOT PRINTABLE...
         ADD       CHAR_COUNT,1        ;ADD 1 TO CHAR COUNT
         ADC       CHAR_CT_CARRY,0     ;AND ONE EXTRY IN CASE OVERFLOW
         JMP       NOCR                ;CAN'T BE...
DELIMITER:
         CMP       AL,0DH              ;A CR ?
         JNE       NOCR
         ADD       LINE_COUNT,1
         ADC       LINE_CT_CARRY,0
NOCR:
         LOOP      GET_CHAR            ;AND CONTINUE...
         JMP       READ                ;NEXT BLOCK WHEN LOOP EXPIRED
;
;
; SUBROUTINE AREA BEGINS
;
DISPLAY: MOV       DL,10               ;LINEFEED FIRST
         MOV       AH,02               ;JUST TO MAKE OUTPUT PRETTY
         INT       21H                 ;CP WRITES OUTPUT
         CMP       CHAR_CT_CARRY,0     ;DID CHAR COUNT OVERFLOW?
         JZ        NO_CARRY            ;NO JUST CONTINUE
         MOV       DX,OFFSET CARRY_64K
         MOV       AH,9                ;AT LEAST THAT MANY + MORE...
         INT       21H                 ;
NO_CARRY:MOV       BX,CHAR_COUNT       ;SAME WITH LOW HALF
         CALL      NUMBERS
         MOV       DX,OFFSET ALPHA_STRING
         CALL      DISPLAY_TEXT
         CMP       FSIZE_CY,0
         JZ        NOFCY               ;NO FILE CARRY
         MOV       DX,OFFSET CARRY_64K
         MOV       AH,09H
         INT       21H                 ;WRITE THE MESSAGE
NOFCY:   MOV       BX,FSIZE            ;THE COMPLETE SIZE
         CALL      NUMBERS             ;WRITE THE TOTAL SIZE...
         MOV       DX,OFFSET FILE_SIZE
         CALL      DISPLAY_TEXT        ;WRITE IT WITH CHARACTERS
         CMP       LINE_CT_CARRY,0
         JZ        NOCRY               ;NO CR CARRY VALUE USED
         MOV       DX,OFFSET CARRY_64K
         MOV       AH,09
         INT       21H
NOCRY:
         MOV       BX,LINE_COUNT
         CALL      NUMBERS
         MOV       DX,OFFSET LINE_STRING
         CALL      DISPLAY_TEXT
         CALL      PGCALC
         CALL      NUMBERS             ;BX ALREADY SET
         MOV       DX,OFFSET PAGE_STRING
         CALL      DISPLAY_TEXT        ;WRITE IT.
         RET                           ;FINSHED AT LAST...
;
;
NUMBERS: MOV       CX,10000            ;GET 10KS.
         CALL      DIVIDE              ;
         MOV       CX,1000             ;1KS
         CALL      DIVIDE
TENTHS:  MOV       CX,100              ;100S
         CALL      DIVIDE
         MOV       CX,10
         CALL      DIVIDE
         MOV       CX,1
         CALL      DIVIDE
         MOV       DISPLAY_FLAG,0
         RET                           ;BACK TO CALLER...
;
;
DIVIDE:  MOV       AX,BX
         XOR       DX,DX
         DIV       CX
         MOV       BX,DX
         MOV       DL,AL
         CMP       AL,0
         JZ        FLAG
         OR        DISPLAY_FLAG,AL
FLAG:    CMP       DISPLAY_FLAG,0
         JNZ       DISP_NUMBER
         MOV       DL,-10H             ;PAD WITH BLANKS.
DISP_NUMBER:
         ADD       DL,30H              ;ASCII WEIGHT
         MOV       AH,2H               ;DISPLAY VIA CP
         INT       21H
         RET                           ;CP RETURNS
;
;
DISPLAY_TEXT:
         MOV       AH,09H              ;WRITE A MSG WITH CP
         INT       21H
         RET                           ;BACK TO CALLER
;
;
;
PGCALC:
         MOV       AX,LINE_COUNT
         XOR       DX,DX
         MOV       BX,MAXPAGE
         DIV       BX
         CMP       AX,0
         JNE       NOINCR              ;IF NEEDED
         INC       AX
NOINCR:  MOV       BX,AX               ;BX IS SET
         CMP       DX,0                ;WAS IT EVEN DIVISION?
         JE        NOFIX               ;YES - BLOW OUT
         INC       BX                  ;OTHERWISE, HANDLE THE REMAINDER
         CMP       AX,66               ;BUT NOT IF < 66 TO START ...
         JA        NOFIX               ;OK AS IS...
         DEC       BX                  ;RESTORE TO 1
NOFIX:
         RET                           ;ALL SET...
;
BUFFER:                                ;MARK BUFFER ZONE...
CSECT    ENDS
         END       ENTRY               ;COMPLETED.
