Category : C++ Source Code
Archive   : VCCRT2.ZIP
Filename : _FILBUF.ASM

 
Output of file : _FILBUF.ASM contained in archive : VCCRT2.ZIP
page ,132
title _filbuf - fill buffer and get character
;***
;_filbuf.asm - fill buffer and get character
;
; Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
;
;Purpose:
; defines _filbuf() - fill buffer and read first character, allocate
; buffer if there is none. Used by the getc() macro. Also directly
; referenced in FREAD.ASM.
;
;*******************************************************************************
;
; --- C VERSION OF ROUTINE
;
; #include
; #include
; #include
; #include
; #include
; #include
; #include
; #ifdef MTHREAD
; #include
; #endif
;
;
; int cdecl _LOAD_DS
; _filbuf (str)
; FILE *str;
; {
; REG1 FILE _NEAR_ *stream;
; REG2 FILE2 _NEAR_ *stream2;
;
; assert(str,"str==NULL");
;
; /* Init pointer to _iob2 entry. */
; stream = (FILE _NEAR_ *) FP_OFF(str);
; stream2 = &(_iob2_(stream));
;
; if (!inuse(stream) || stream->_flag & _IOSTRG)
; return(EOF);
;
; if (stream->_flag & _IOWRT) {
; stream->_flag |= _IOERR;
; return(EOF);
; }
;
; stream->_flag |= _IOREAD;
;
; /* Get a buffer, if necessary. */
;
; if (!anybuf2(stream,stream2))
; _getbuf(stream);
; else
; stream->_ptr = stream->_base;
;
; stream->_cnt = _read(fileno(stream), stream->_base, stream2->_bufsiz);
;
; if ((stream->_cnt == 0) || (stream->_cnt == -1)) {
; stream->_flag |= stream->_cnt ? _IOERR : _IOEOF;
; stream->_cnt = 0;
; return(EOF);
; }
;
; if ( !(stream->_flag & (_IOWRT|_IORW))
; && ((_osfile[fileno(stream)] & (FTEXT|FEOFLAG)) == (FTEXT|FEOFLAG)) )
; stream2->_flag2 |= _IOCTRLZ;
;
; stream->_cnt--;
;
; return(0xff & *stream->_ptr++);
; }
;
; --- END OF C VERSION
;
.xlist
include version.inc
include cmacros.inc
include stdio.inc
include msdos.inc
.list

sBegin data
assumes ds,data

externW _iob
externW _iob2
externB _osfile ; array of handle attributes

sEnd data

externNP _getbuf ; buffer a stream
externP _read ; write to file handle


sBegin code
assumes cs,code
assumes ds,data

;***
;int _filbuf(stream) - fill buffer and get first character
;
;Purpose:
; get a buffer if the file doesn't have one, read into it, return first char.
; try to get a buffer, if a user buffer is not assigned. intended to be
; called by the user only thru the getc macro. assume no input stream is to
; remain unbuffered when memory is available unless it is marked _IONBF. at
; worst, give it a single char buffer. the need for a buffer, no matter how
; small, becomes evident when we consider the ungetc's necessary in scanf
;
; [NOTE 1: Multi-thread - _filbuf() assumes that the caller has aquired
; the stream lock, if needed.]
;
; [NOTE 2: The code depends on _iob[] and _iob2[] being near arrays of the
; total size and element size.]
;
; [NOTE 3: The use of _IOCTRLZ is tied closely to ftell() and also to
; lowio read()'s FEOFLAG flag.]
;
;Entry:
; FILE *stream - stream to read from
;
;Exit:
; returns first character from buffer (next character to be read)
; returns EOF if the FILE is actually a string, or not open for reading, or
; if open for writing or if no more chars to read.
; all fields in FILE structure may be changed except _file.
;
;Exceptions:
;
;*******************************************************************************


cProc _filbuf,,

parmDP stream

cBegin

mov si,word ptr [stream] ; set si = stream = _iob entry
mov al,[si]._flag ; set al = stream->_flag

;**
; Check that stream is in use, and neither _IOSTRG nor _IOWRT
; is set.

test al,(_IOREAD OR _IORW OR _IOWRT) ; stream in use?
jz reteof ; no, error
test al,_IOSTRG ; is it a string iob?
jnz reteof ; yup, error
test al,_IOWRT ; write only file?
jnz seterr1 ; yup, error

;**
; Set:
; set _IOREAD (in stream->_flag)
; di = _iob2 entry (i.e., stream2 pointer)

or al,_IOREAD
mov [si]._flag,al

mov di,si
sub di,dataOFFSET _iob
add di,dataOFFSET _iob2

test al,_IOMYBUF OR _IONBF
jnz doread
test [di]._flag2,_IOYOURBUF
jnz doread

;**
; No buffer, try to get one.

if sizeD
push ds ; push arg
push si
else
push si ; push arg
endif

call _getbuf ; _getbuf(stream)

if sizeD
add sp,4 ; clean off arg
else
pop ax ; clean off arg
endif
; fall thru

;**
; Call lowio's read() to fill the buffer. Note that if the stream/handle
; is in text mode, the number of bytes read may well be less than _bufsiz.

doread:
mov ax,word ptr [si]._base ; set _ptr equal to _base (note: even
mov word ptr [si]._ptr,ax ; in large model, only need to change
; the offset portino of _ptr)
push [di]._bufsiz ; push args

if sizeD
push word ptr [si]._base + 2
push ax
else
push ax
endif

xor bx,bx
mov bl,[si]._file ; bl=_file / bh=0 (for later)
push bx

callcrt _read ; _read(_file, _base, _bufsiz)

if sizeD
add sp,8 ; clean off stack
else
add sp,6 ; clean off stack
endif

or ax,ax ; 0 bytes read?
jz seteof ; yes, we've hit eof
cmp ax,-1 ; did an error occur?
jne read_ok ; no, continue with good read code
;fall through to seterr2 ; yes, go set _flag and ret value

;**
; --- Error handling code ---
; (located in the middle of the source so all paths can get to it)
;

seterr2:
or [si]._flag,_IOERR
jmp short zerocnt

seterr1:
or [si]._flag,_IOERR
jmp short reteof

seteof:
or [si]._flag,_IOEOF
; fall thru

zerocnt:
mov [si]._cnt,0
; fall thru

reteof:
mov ax,EOF
jmp short done ; return the error

;** **

;**
; The call to read() was successful.
;**
; If the file is read-only, text mode, and we hit a ^Z char, set _IOCTRLZ flag.
; ax = read count
; bl=stream->_file
; bh=0

read_ok:
mov bh,byte ptr [bx + dataOFFSET _osfile] ; bh =_osfile[fd]
and bh,(FTEXT OR FEOFLAG) ; get lowio text mode and ^Z bits
cmp bh,(FTEXT OR FEOFLAG) ; are they both on ??
jne end_ctrlz ; if not, jump out

mov bh,[si]._flag ; bh = stream->_flag
test bh,(_IORW OR _IOWRT) ; is file read-only ??
jnz end_ctrlz ; if not, jump out

or [di]._flag2,_IOCTRLZ ; flip ^Z flag on

end_ctrlz:

;**
; Get the first char out of the stream buffer (to be the return value).
; ax = read count

dec ax
mov [si]._cnt,ax

if sizeD
les bx,[si]._ptr
xor ax,ax
mov al,byte ptr es:[bx]
else
mov bx,[si]._ptr
xor ax,ax
mov al,byte ptr [bx]
endif

inc bx
mov word ptr [si]._ptr,bx

done:
cEnd

sEnd code
end


  3 Responses to “Category : C++ Source Code
Archive   : VCCRT2.ZIP
Filename : _FILBUF.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/