Metropoli BBS
VIEWER: typefile.asm MODE: TEXT (ASCII)
;  TYPEFILE.ASM -- Simple demo of RFILE subroutine (MS-DOS version).  
;                  Displays text file on standard output device.
;  Copyright (c) 1989 Ziff Communications Co.
;  PC Magazine * Ray Duncan
;  Requires: RFILE.ASM, STRINGS1.ASM, ARGV.ASM, ARGC.ASM.
;
;  Build:       MASM TYPEFILE;
;               MASM RFILE;
;               MASM STRINGS1;
;               MASM ARGC;
;               MASM ARGV;
;               LINK TYPEFILE+RFILE+STRINGS1+ARGC+ARGV;
;
;  Usage:       TYPEFILE filename.ext

cr      equ     0dh             ; ASCII carriage return
lf      equ     0ah             ; ASCII line feed
blank   equ     20h             ; ASCII space code

blksize equ     256             ; size of input file buffer     

cmd     equ     80h             ; buffer for command tail

stdin   equ     0               ; standard input handle
stdout  equ     1               ; standard output handle
stderr  equ     2               ; standard error handle

DGROUP  group   _DATA,STACK

_TEXT   segment word public 'CODE'

        extrn   argc:near       ; external subroutines
        extrn   argv:near
        extrn   rline:near

        assume  cs:_TEXT,ds:DGROUP,es:NOTHING,ss:STACK

main    proc    far             ; entry point from MS-DOS

        mov     ax,DGROUP       ; make our data segment
        mov     ds,ax           ; addressable via DS
                                ; (leave ES = PSP segment)

                                ; check if filename present
        mov     bx,offset cmd   ; ES:BX = command tail
        call    argc            ; count command arguments
        cmp     ax,2            ; are there 2 arguments?
        je      main1           ; yes, proceed

                                ; missing filename, display
                                ; error message and exit
        mov     dx,offset msg2  ; DS:DX = message address
        mov     cx,msg2_len     ; CX = message length
        jmp     main5           ; go display it

main1:                          ; get address of filename
        mov     ax,1            ; AX = argument number
                                ; ES:BX still = command tail
        call    argv            ; returns ES:BX = address,
                                ; and AX = length

        mov     di,offset fname ; copy filename to buffer
        mov     cx,ax           ; CX = length

main2:  mov     al,es:[bx]      ; copy one byte
        mov     [di],al
        inc     bx              ; bump string pointers
        inc     di
        loop    main2           ; loop until string done
        mov     byte ptr [di],0 ; add terminal null byte

        push    ds              ; set ES = DGROUP too
        pop     es
        assume  es:DGROUP

                                ; now open the file...
        mov     ax,3d00h        ; Fxn 3DH = open file
                                ; mode 0 = read only
        mov     dx,offset fname ; DS:DX = filename
        int     21h             ; transfer to MS-DOS
        mov     fhandle,ax      ; save file handle
        jnc     main3           ; jump, open successful

                                ; file doesn't exist
        mov     dx,offset msg1  ; DS:DX = error message
        mov     cx,msg1_len     ; CX = message length
        jmp     main5           ; go display it

main3:                          ; read line from file
        mov     bx,fhandle      ; BX = file handle
        mov     cx,blksize      ; CX = buffer length
        mov     dx,offset fbuff ; DS:DX = buffer
        call    rline
        or      ax,ax           ; reached end of file?
        jz      main4           ; yes, exit

                                ; otherwise display line
        mov     cx,ax           ; line length
        mov     bx,stdout       ; standard output handle
        mov     ah,40h          ; Function 40H = write
        int     21h             ; transfer to MS-DOS

        jmp     main3           ; get another line

main4:                          ; success exit point
        mov     bx,fhandle      ; BX = file handle
        mov     ah,3eh          ; Fxn 3EH = close
        int     21h             ; transfer to MS-DOS

        mov     ax,4c00h        ; Fxn 4CH = terminate,
                                ; return code = 0
        int     21h             ; transfer to MS-DOS

main5:                          ; common error exit
                                ; DS:DX = message address
                                ; CX = message length
        mov     bx,stderr       ; standard error handle
        mov     ah,40h          ; Fxn 40H = write
        int     21h             ; transfer to MS-DOS

        mov     ax,4c01h        ; Fxn 4CH = terminate,
                                ; return code = 1
        int     21h             ; transfer to MS-DOS
        
main    endp


_TEXT    ends


_DATA   segment word public 'DATA'

fname   db      64 dup (0)      ; buffer for input filespec

fhandle dw      0               ; input file handle

fbuff   db      blksize dup (?) ; data from input file

msg1    db      cr,lf
        db      'typefile: file not found'
        db      cr,lf
msg1_len equ    $-msg1

msg2    db      cr,lf
        db      'typefile: missing filename'
        db      cr,lf
msg2_len equ    $-msg2

_DATA   ends    


STACK   segment para stack 'STACK'

        db      64 dup (?)

STACK   ends
        end     main
[ RETURN TO DIRECTORY ]