TITLE Supplement to SPEECH.COM by Douglas Sisco      09-04-1985
PAGE    55,132           

CODE    SEGMENT 'CODE'
        ASSUME CS:CODE,DS:CODE
        ORG     100H

BEGIN:  JMP     START

; Put my name in .COM file - can be viewed with TYPE command.
        DB      8,8,8,'Program by Douglas Sisco 9-6-85',13,10,26 


STRING  DB      255 DUP(0)              ; Line input buffer to hold 255 chars

; Here is a fake string descriptor  - BASIC Manual C-8
; SPEECH expects a pointer to this on the stack when it is called

STRLEN  DB      0
STROFS  DW      STRING

INBYTE  DB      0                       ;One byte file input buffer
HAND    DW      0                       ;File handle from DOS

SPEECH   DW      0972                   ;DWORD Pointer to Speech
         DW      0000                   ;This is where it is put 0000:03CCH

NOSPEECH DB      'Speech Program not loaded - run SPEECH.COM and try again',13,10,'$'
FNFMSG   DB      'Can not open file',13,10,'$'
ERRMSG   DB      'DOS error '
ERRCD    DB      '  -- failed read attempt',13,10,'$'
EOF      DB      0                      ;File exist/EOF flag

START:  XOR     AX,AX
        MOV     DS,AX
        MOV     AL,DS:[3CCH]            ;See if SPEECH.COM is in memory
        CMP     AL,0CDH
        PUSH    CS
        PUSH    CS
        POP     ES                      ;All segment regs = CS
        POP     DS
        JZ      OK

        MOV     AH,9
        MOV     DX,OFFSET NOSPEECH      ;Print message if not
        INT     21H
        INT     20H                     ;Return to DOS
OK:
        XOR     AX,AX
        MOV     AL,DS:[80H]
        MOV     DI,81H
        ADD     DI,AX
        MOV     BYTE PTR [DI],0         ;Put a 0 at end of command line

        CALL    OPEN                    ;Open the file for read
        JNC     OK2

        MOV     AH,9
        MOV     DX,OFFSET FNFMSG
        INT     21H                     ;Print message
        INT     20H                     ;Dont try it on non-existant files

OK2:
        CALL    READLIN                 ;Read line

        CMP     STRLEN,0
        JZ      OK3                     ;Str Length = 0 - Don't bother

        MOV     AX,OFFSET STRLEN

        PUSH    AX                      ;Pass data location to speech program
        CALL    DWORD PTR SPEECH        ;Say it
OK3:
        CMP     EOF,0                   ;EOF ?
        JNZ     S1
        JMP     OK2
S1:
        CALL    CLOSE                   ;Close file
        INT     20H                     ;Return to DOS
;--------------------
OPEN    PROC    NEAR                    ;Attempt to OPEN file
        MOV     DX,82H
        MOV     AX,3D00H                ;Open for read
        INT     21H                     ;Leave all flags for caller to process
        MOV     HAND,AX
        RET
OPEN    ENDP
;--------------------
READLIN PROC    NEAR                    ;Read line from file
        MOV     STRLEN,0
        MOV     DI,OFFSET STRING
R3:
        MOV     DX,OFFSET INBYTE
        MOV     BX,HAND                 ;Get handle from OPEN
        MOV     AX,3F00H
        MOV     CX,1                    ;Read 1 byte
        INT     21H
        JNC     R6                      ;Check for error

        ADD     AL,'0'
        MOV     ERRCD,AL
        MOV     DX,OFFSET ERRMSG
        MOV     AH,9
        INT     21H                     ;Print error message
        XOR     AX,AX                   ;Cause flag to be set
R6:
        OR      AX,AX                   ;See if end of file
        JNZ     R4 
        MOV     INBYTE,26                ;force EOF
R4:
        MOV     DL,INBYTE
        MOV     AH,2
        INT     21H                     ;Print Char on console 

        CMP     INBYTE,' '              ;See if char will work
        JB      R5
        CMP     INBYTE,'~'
        JA      R5
        CMP     STRLEN,254
        JA      R5                      ;Line Too Long

        INC     STRLEN                  ;Add char to string
        MOV     AL,INBYTE
        STOSB                           ;Move char to string

R5:     CMP     INBYTE,26               ;^Z ? set eof flag if yes
        JNZ     R1
        MOV     EOF,1
        MOV     INBYTE,13               ;Force true for next CMP
R1:     CMP     INBYTE,13               ;use CR for EOL marker LF is ignored
        JZ      R2
        JMP     R3
R2:     RET
READLIN ENDP
;--------------------
CLOSE   PROC    NEAR
        MOV     BX,HAND
        MOV     AH,3EH
        INT     21H
        RET
CLOSE   ENDP
;--------------------
CODE    ENDS
        END     BEGIN
 

