📄 dkio.asm
字号:
;Preserves:
; BX
;Exceptions:
; B$ERR_BRN -- bad record number
;*******************************************************************************
cProc GetFilePos,<NEAR>
cBegin
MOV AX,1 ; ask for seek to current + (zero) offset
SKIP 2 ; skip over SeekToStart
cEnd <nogen> ; fall into SeekZeroOffset
;***
;SeekToStart -- seek to start of file. Added with [19].
;
;Purpose:
; Seek from start of file with offset 0
;Entry:
; (ES:)[SI] = *FDB
;Exit:
; file position is set to start of file.
; [DX|AX] = start file position
;Uses:
; Per convention
;Preserves:
; BX
;Exceptions:
; B$ERR_BRN -- bad record number
;*******************************************************************************
cProc SeekToStart,<NEAR>
cBegin
XOR AX,AX ; seek from start
cEnd <nogen> ; fall into SeekZeroOffset
;***
;SeekZeroOffset -- Do seek from offset zero. Added with [19].
;
;Purpose:
; Get file position by seeking with method in AX with offset 0.
;Entry:
; (ES:)[SI] = *FDB
; AX = seek method (described in DosSeek)
;Exit:
; [DX|AX] = current file position
;Uses:
; Per convention
;Preserves:
; BX
;Exceptions:
; B$ERR_BRN -- bad record number
;*******************************************************************************
cProc SeekZeroOffset,<NEAR>
cBegin
XOR CX,CX ; set offset to zero
MOV DX,CX
cEnd <nogen> ; fall into DosSeek
;***
;DosSeek
;
;Purpose:
; Seek to the location desired.
;Entry:
; (ES:)[SI] = *FDB
; [DX|CX] = distance to move
; [AX] = seek method (0, 1 or 2)
; 0 = seek from start
; 1 = seek from current
; 2 = seek from end
;Exit:
; If no error
; [DX|AX] = has the result (seg:off)
;Uses:
; Per convention
;
;Preserves:
; BX
;Exceptions:
; B$ERR_BRN -- bad record number
;
;*******************************************************************************
cProc DosSeek,<NEAR>,<BX>
cBegin
XCHG CX,DX ; [CX|DX] = position
CALLOS LSeek,ERCBRN2,<FileDB.FD_HANDLE>
FDB_PTR ES ;refresh FDB SEG jic global memory moved
cEnd
SUBTTL disk LOF
page
;***
;DISK_LOF -- length of the file
;
;Purpose:
; Returns the length of the file.
;
; If the file is a communications file, LOF returns the free spaces in
; the buffer.
;Entry:
; (ES:)[SI] = *FDB
;Exit:
; [DX|AX] = length of the file
;Uses:
; none
;Exceptions:
; B$ERR_BRN -- bad record number
;*******************************************************************************
cProc DISK_LOF,<NEAR>
cBegin
TEST FileDB.FD_FLAGS,FL_CHAR ;is character device ?
JNZ CharDevLOF ;Brif yes
TEST FileDB.FD_MODE,MD_SQO OR MD_APP ; output or append?
JZ NotOutApp ; Brif not -- don't flush buffer
CALL B$FLUSH ; flush buffer if it contains data
; (this MIGHT increase file size)
NotOutApp:
CALL GetFilePos ; [DX|AX] = position
PUSH DX ; save current position
PUSH AX
cCall B$FILESIZE ; get file size in [DX|AX]
POP CX ; CX = low word of current pos
POP BX ; BX = high word of current pos
PUSH DX ; save file size
PUSH AX
MOV DX,BX ; [DX|CX] = original position
CALL B$SeekFromStart ; set file original position
POP AX ; get file size back
POP DX
JMP SHORT LOFExit
CharDevLOF:
MOV AX,1 ;non-random length is 1
XOR DX,DX
TEST FileDB.FD_MODE,MD_RND+MD_BIN ; random or binary?
JE LOFExit ; Brif not -- exit
MOV AX,FileDB.FD_FSIZ_LO
MOV DX,FileDB.FD_FSIZ_HI
LOFExit:
cEnd ;exit
SUBTTL disk WIDTH
page
;***
;DISK_WIDTH -- set file width
;
;Purpose:
; Set file width while the file is open.
;Entry:
; (ES:)[SI] = *FDB
; [DL] = file width
;Exit:
; file width is set.
;Uses:
; none
;Preserves: (optional)
; all
;Exceptions:
; none
;*******************************************************************************
cProc DISK_WIDTH,<NEAR>
cBegin
MOV FileDB.FD_WIDTH,DL ;set file width
cEnd
SUBTTL get output position
page
;***
;DISK_GPOS -- get output position
;
;Purpose:
; Get current output position.
;Entry:
; (ES:)[SI] = *FDB
;Exit:
; [AH] = current output position
;Uses:
; none
;Preserves: (optional)
; all
;Exceptions:
; none
;*******************************************************************************
cProc DISK_GPOS,<NEAR>
cBegin
MOV AH,FileDB.FD_OUTPS ;get file output position
cEnd
SUBTTL get file width
page
;***
;DISK_GWID -- get file width
;
;Purpose:
; Get file width.
;Entry:
; (ES:)[SI] = *FDB
;Exit:
; [AH] = file width
;Uses:
; none
;Preserves: (optional)
; all
;Exceptions:
; none
;*******************************************************************************
cProc DISK_GWID,<NEAR>
cBegin
MOV AH,FileDB.FD_WIDTH ;get file width
cEnd
DISK_DWID EQU B$ERR_FC ; illegal funtion call error
SUBTTL disk serial input
page
;***
;B$DISK_SINP --disk serial input
;B$IDISK_SINP -- Far (QB3) interface for disk serial input
;
;Purpose:
; Input one character from disk.
;
; This routine is terrible. It has four exit points -- namely,
;
; SetEofFlag -- when read null from disk, set flag and carry and exit
; EofFlag -- when an EOF character is read, or the EOF flag has been
; set, set carry and exit
; NotEofExit -- when a normal character is get, clear carry and exit
; SinpExit -- final exit point, just exit (usually the carry has been
; processed and exit via this point)
;Entry:
;Exit:
; [AL] = char
; [CX] = 0 if EOF detected (B$IDISK_SINP only)
; FDB deallocated and file closed if error and called from OPEN
;Uses:
; none
;Preserves:
; BX,CX,DX,DI
;Exceptions:
; B$ERR_FWP -- permission denied
; B$ERR_ACD -- path/file access error
; B$ERR_FOV -- field overflow (from FovChk)
;*******************************************************************************
cProc B$IDISK_SINP,<PUBLIC,FAR>,<SI>
cBegin
FDB_PTR ES,SI,b$PTRFIL ;get FDB pointer
DbAssertRel SI,NE,0,DK_TEXT,<Invalid FDB ptr in B$IDISK_SINP>
OR FileDB.FD_FLAGS,FL_BIN ; specify binary access (no ^Z EOF)
cCall B$DISK_SINP ;call disk seq input
MOV CX,0 ; don't touch flags
JC BISINPExit ;brif end of file
DEC CX ;set CX non zero
BISINPExit:
cEnd
labelNP DISK_SINP
cProc B$DISK_SINP,<PUBLIC,NEAR>,<BX,CX,DX,DI> ;save BX,CX,DX,DI
cBegin
TEST FileDB.FD_FLAGS,FL_NEOF ;had EOF encountered ?
JZ EofExit ;Brif EOF
CMP FileDB.FD_MODE,MD_RND
JE RndGetChar ;input from random
LEA DI,FileDB.FD_BUFFER ;DI=*buffer
MOV BX,FileDB.FD_BUFCNT ;BX = next unread char position
CMP BX,FileDB.FD_INBUFCNT ;any unread chars left ?
JNE GetOneChar ;Brif yes, go get it
MOV AL,NOT PUTFLG ;indicate read
MOV BX,FileDB.FD_VRECL ;length to be read
PUSH ES ;preserve ES
PUSH DS ;set ES=DS
POP ES
cCall DosReadWrite ;fill one buffer, on return
; if CY then error, & AX=error code
; else AX has the actual read/write
; bytes
POP ES ;recover ES
JB B$AnalyzeErr ; Brif error
FDB_PTR ES ;freshen FDB seg
OR AX,AX ; is end-of-file ?
JZ SetEofFlag ;Brif yes, set FD_FLAGS
MOV FileDB.FD_INBUFCNT,AX ; set # bytes in input buffer
XOR BX,BX ; get from the begining of buffer
MOV FileDB.FD_BUFCNT,BX ; # read bytes in buffer = 0
GetOneChar:
MOV AL,FileDB.FD_BUFFER[BX] ;get byte from buffer[BX]
INC FileDB.FD_BUFCNT ;one less in the buffer
TEST FileDB.FD_FLAGS,FL_CHAR+FL_BIN ;EOF is nonsensical for char
; devices or binary files
JNZ SinpExit ;Brif yes (exit with NC)
CMP AL,EOFCHR ;is EOF char ?
JNZ NotEofExit ;exit
cCall DISK_BAKC ;backup to keep EOF
SetEofFlag:
AND FileDB.FD_FLAGS,NOT FL_NEOF ;set EOF flag
EofExit: ;EOF encountered
MOV AL,EOFCHR ;return EOF character
STC ;set carry
JMP SHORT SinpExit ;exit
RndGetChar: ;input from random file
CALL FovChk ;field overflow check, on return
; BX has the current offset
MOV AL,FileDB.FD_BUFFER[BX-1] ;get character
NotEofExit: ;clear carry and exit
CLC ;clear carry
SinpExit:
cEnd ; pop bx,di, and exit
PAGE
;***
; B$AnalyzeErr, B$OpenErr -- analyze error code, and give proper error.
;
;Purpose:
; Save some code and standardize error reporting by file I/O routines.
;Entry:
; AX = error code from DosReadWrite
; For B$AnalyzeErr, SI = *FDB (or 0 if no FDB)
;Exit:
; None
;Uses:
; None
;
;Exceptions:
; B$ERR_IOE -- device I/O error
; B$ERR_FWP -- permission denied
; B$ERR_ACD -- path/file access error
;
;******************************************************************************
cProc B$AnalyzeErr,<NEAR>
cBegin
OR SI,SI ; valid FDB?
JZ B$OpenErr ; brif not
FDB_PTR ES ; restore FDB SEG in ES
TEST FileDB.FD_FLAGS,FL_CHAR ; char device ?
PUSHF ; save this test
CALL B$TEST_CLOSE ; if closing flag set, close file
; and deallocate FDB
POPF ; char device?
JNZ DeviceIOError ; brif so -- device I/O error
labelNP <PUBLIC,B$OpenErr>
cCall B$GETEXTERR ; ZF if DOS 3 and sharing/locking error
JNZ PathAccessError ; brif not (DOS 3 and sharing/locking)
PermissionDenied:
JMP B$ERR_FWP ; Permission denied error
PathAccessError:
JMP B$ERR_ACD ; Path/File access error
DeviceIOError:
JMP B$ERR_IOE ; device I/O error
cEnd <nogen> ; nothing leaves from here
;***
;FovChk -- field overflow check
;
;Purpose:
; Check whether the field is overflow.
;Entry:
; (ES:)[SI] = *FDB
;Exit:
; [BX] = updated position in the buffer
;Uses:
; none
;Exceptions:
; B$ERR_FOV -- field overflow
;*******************************************************************************
cProc FovChk,<NEAR>
cBegin
MOV BX,FileDB.FD_BUFCNT ;get current position
CMP BX,FileDB.FD_VRECL ;check for end of record
JE ERCFOV ;Yes - field overflow
INC BX ;bump pointer
MOV FileDB.FD_BUFCNT,BX ;update position
cEnd ;exit
ERCFOV:
MOV AX,B$ENTRY_BUFCNT ; Restoring the buffer position
MOV FileDB.FD_BUFCNT,AX ; to what it was before execution
; of current statement
JMP B$ERR_FOV ; Field Over Flow Error
page
;***
; B$CHK_WRITE -- Check to see that we got what we requested.
; Added as part of [20].
;
;Purpose:
;
;Entry:
; (ES:)[SI] = *FDB
;
;Exit:
; None
;Uses:
; Flags
;
;Preserves:
; All
;
;Exceptions:
; B$ERR_DFL -- disk full
; B$ERR_IOE -- I/O error
;
;******************************************************************************
cProc B$CHK_WRITE,<NEAR>
cBegin
CMP AX,CX ; bytes written the same as required ?
JE GotAll ; Brif yes -- no error
; Check for DOS 2.0 bug when writing to CONOUT. DOS 2.0 reports
; n-1 bytes written when requested to write n bytes to CON when
; CON is in raw mode.
TEST FileDB.FD_FLAGS,FL_CONOUT ; Is this CON OUT?
JZ Shortchanged ; brif not -- error
PUSH AX ; save return count
INC AX ; Add one to count
CMP AX,CX ; did DOS report 1 less requested count?
POP AX ; restore register
JE GotAll ; Brif so -- no error
Shortchanged:
TEST FileDB.FD_FLAGS,FL_CHAR ; char device?
PUSHF ; save this test
MOV b$CLOS_FDB,SI ; make B$TEST_CLOSE close file
CALL B$TEST_CLOSE ; close file with NO ERROR CHECKING,
; and deallocate FDB
POPF ; was it a char device?
JNZ DeviceIOError ; brif so -- I/O error
JMP B$ERR_DFL ; give disk full error
GotAll:
cEnd
SUBTTL disk serial output
page
;***
;DISK_SOUT -- disk serial output
;
;Purpose:
; Output one char to a file.
;Entry:
; (ES:)[SI] = *FDB
; [AL] = character
;Exit:
; none
;Uses:
; none
;Preserves:
; BX
;Exceptions:
; B$ERR_FOV -- field overflow (from FovChk)
;*******************************************************************************
;***
;B$UpdateOUTPS - Update the OUTPS field of a FDB
;
;Purpose:
; This shared code correctly sets the OUTPS field of a FDB for
; a new character that is entered into the output buffer.
;
;Entry:
; AL - character being entered into FDB output buffer
; (ES:)[SI] = *FDB
;
;Exit:
; FileDB.FD_OUTPS set properly
;
;Uses:
; Flags.
;
;Preserves:
; None.
;
;Exceptions:
; None.
;*******************************************************************************
DbPub DISK_SOUT
cProc DISK_SOUT,<NEAR>
cBegin
CMP FileDB.FD_MODE,MD_RND
JE RndWrtChar ;serial output to random
TEST FileDB.FD_FLAGS,FL_CHAR ;can't write EOF char to a char device
JZ NotCharDev
CMP AL,EOFCHR ;is EOF char ?
JE SoutExit ;Brif yes, exit
NotCharDev:
PUSH BX ; save BX
MOV BX,FileDB.FD_BUFCNT ;# in buffer
CMP BX,FileDB.FD_VRECL ;is full ?
JB BufferReady ;Brif not, no flush buffer
PUSH CX ; B$FLUSH destroys CX
CALL B$FLUSH ; flush the buffer
POP CX
XOR BX,BX ; new offset into buffer is 0
; prior to this change, the buffer was cleared with ClearBuffer
; each flush. This should not be needed for output files.
BufferReady:
MOV FileDB.FD_BUFFER[BX],AL ;store char in buffer
INC FileDB.FD_BUFCNT ;update buffer count
JMP SHORT UpdateCurloc
RndWrtChar: ;serial output to random file
PUSH BX ; save BX
cCall FovChk ;check for field overflow, on return
; BX is the updated buffer offset
MOV FileDB.FD_BUFFER[BX-1],AL ;store character
UpdateCurloc:
POP BX ; get back BX
CMP AL,NEWLINE ;is new line ?
JNZ UpdateOutpos ;Brif not
MOV FileDB.FD_OUTPS,0 ;zero position
JMP SHORT SoutExit ;exit
UpdateOutpos: ;update current location
CMP AL,' ' ;is printable character ?
; (NC if yes)
CMC ;reverse the carry
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -