home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programming
/
powerprogramming1994.iso
/
progtool
/
asmutl
/
bluebook.arc
/
FILES.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-05-11
|
12KB
|
386 lines
COMMENT ~
FILES.ASM -- File manipulation Procedures
From `BLUEBOOK of ASSEMBLY ROUTINES for the IBM PC & XT'
by Christopher L. Morgan
Copyright (C) 1984 by The Waite Group, Inc.
Contents:
---------
CBUF_CLR -- Clear the circular buffer
CBUF_IN -- Input to circular buffer
CBUF_INIT -- Initialize a circular buffer
CBUF_OUT -- Output to a circular buffer
CBUF_PUT -- Put a byte into a circular buffer
CLOS_FIL -- Close a file
EMSG_OUT -- Exception message output
FILT_CR* -- Filter for carriage return/linefeed
MAKE_FIL -- Create a file
READ_FIL -- Read bytes from a file
SAVE -- Save a file from communications line to disk
WRIT_FIL -- Write bytes to a file
>>>>> See FILES.DOC for complete descriptions of these routines. <<<<<
------------------------------------------------------------------------------
It is better to put this data in the source code calling these routines, and
then comment out this section. ~
DATAS SEGMENT PUBLIC
CR EQU 0DH ;ASCII code for carriage return
LF EQU 0AH ;ASCII code for linefeed
CTRL_Z EQU 1AH ;ASCII code for ^Z
BLK_SIZ = 0 ;K=block size
CBUF_SIZ DW 256 ;K=CBUF max capacity
CBUF DB 1 ;K=base address of CBUF
LBUF DB 256 DUP('LBUF')
NAME_BUF DB 64 DUP('NAME')
;
;Following table used by EMSG_OUT
EMSG DW EMSG1
DW EMSG2
DW EMSG3
DW EMSG4
DW EMSG5
DW EMSG6
DW EMSG7
DW EMSG8
DW EMSG9
DW EMSG10
DW EMSG11
DW EMSG12
DW EMSG13
DW EMSG14
DW EMSG15
DW EMSG16
DW EMSG17
DW EMSG18
EMSG1 DB CR,LF,'Invalid function number',CR,LF,0
EMSG2 DB CR,LF,'File not found',CR,LF,0
EMSG3 DB CR,LF,'Path not found',CR,LF,0
EMSG4 DB CR,LF,'Too many open files',CR,LF,0
EMSG5 DB CR,LF,'Access denied',CR,LF,0
EMSG6 DB CR,LF,'Invalid handle',CR,LF,0
EMSG7 DB CR,LF,'Memory control blocks destroyed',CR,LF,0
EMSG8 DB CR,LF,'Insufficient memory',CR,LF,0
EMSG9 DB CR,LF,'Invalid memory block address',CR,LF,0
EMSG10 DB CR,LF,'Invalid environment',CR,LF,0
EMSG11 DB CR,LF,'Invalid format',CR,LF,0
EMSG12 DB CR,LF,'Invalid access code',CR,LF,0
EMSG13 DB CR,LF,'Invalid data',CR,LF,0
EMSG14 DB CR,LF,'Message not in use',CR,LF,0
EMSG15 DB CR,LF,'Invalid drive was specified',CR,LF,0
EMSG16 DB CR,LF,'Attempted to remove the current directory',CR,LF,0
EMSG17 DB CR,LF,'Not same device',CR,LF,0
EMSG18 DB CR,LF,'No more files',CR,LF,0
DATAS ENDS
;------------------------------------------------------------------------------
;It is better to include this data in the source code calling these routines,
; and then comment out this section.
STACKS SEGMENT STACK
DB 20 DUP(' STACKS ')
STACKS ENDS
;------------------------------------------------------------------------------
CODES SEGMENT
;The following variables/constants must be defined in the source code calling
; these routines. See FILES.DOC.
EXTRN COM_INCK:FAR,COM_INIT:FAR,COM_ON:FAR,COM_OFF:FAR,MSG_OUT:FAR
EXTRN DTA:DWORD,LAST:BYTE,GAUGE:WORD,NEARFULL:WORD,NEAREMPTY:BYTE
PUBLIC EMSG_OUT,GET_SPEC,MAKE_FIL,CLOS_FIL,WRIT_FIL,READ_FIL
PUBLIC CBUF_INIT,CBUF_PUT,CBUF_IN,CBUF_CLR,CBUF_OUT,SAVE
ASSUME CS:CODES,DS:DATAS
;----------------------------I/O ROUTINES--------------------------------------
;Routine to send out exception messages
EMSG_OUT PROC FAR
PUSH SI ;Save registers
PUSH AX
ADD AX,AX ;Double to index through table
MOV SI,AX ;SI points into table
MOV SI,EMSG[SI] ;Look up address of message
CALL MSG_OUT ;Send the message
POP AX ;Restore registers
POP SI
RET
EMSG_OUT ENDP
;------------------------------------------------------------------------------
;Routine to get a file specifier
;
GET_SPEC PROC FAR
PUSH DS ;Save registers
PUSH ES
PUSH SI
PUSH DI
PUSH CX
;
;Set up pointer to DTA to get parameters
LDS SI,DTA ;Point to DTA for parameters
MOV CL,[SI] ;Get length of string
MOV CH,0 ;Make 16-bit
INC SI ;Skip the length byte
MOV AL,' ' ;Scan past the spaces
GET_SPEC1:
CMP [SI],AL ;Check for space
JNE GET_SPEC2 ;Exit loop if nonspace
INC SI ;Else point to next byte
LOOP GET_SPEC1 ;Loop back for more
JCXZ GET_SPEC3 ;No file specifier?
;
;Move the rest into place
GET_SPEC2:
MOV DI,DX ;Index points to destination
CLD ;Forward direction
REP MOVSB ;Make the transfer
CLC ;No error, so no carry
JMP GET_SPEC_XIT ; and return
GET_SPEC3:
MOV AX,20 ;No file specified
STC ;Set carry for error
JMP GET_SPEC_XIT ; and exit
GET_SPEC_XIT:
POP CX ;Restore registers
POP DI
POP SI
POP ES
POP DS
RET
GET_SPEC ENDP
;------------------------------------------------------------------------------
;Routine to create a file
;
MAKE_FIL PROC FAR
PUSH CX ;Save register
MOV CX,0 ;Attribute 0
INT 21H ;DOS call
POP CX ;Restore register
RET
MAKE_FIL ENDP
;------------------------------------------------------------------------------
;Routine to close a file
;
CLOS_FIL PROC FAR
MOV AH,3EH ;Close a file
INT 21H ;DOS call
RET
CLOS_FIL ENDP
;------------------------------------------------------------------------------
;Routine to write bytes to a file
;
WRIT_FIL PROC FAR
MOV AH,40H ;Write to a file
INT 21H ;DOS call
CMP AX,CX ;Was it all written?
JE WRIT_FIL_XIT ;Skip if yes
MOV AX,21 ;Not all bytes were transferred
STC ;Set carry for error
WRIT_FIL_XIT:
RET
WRIT_FIL ENDP
;------------------------------------------------------------------------------
;Routine to read bytes from a file
;
READ_FIL PROC FAR
MOV AH,3FH ;Read from a file
INT 21H ;DOS call
CMP AX,CX ;Everything back?
JE READFIL_XIT ;Skip if yes
MOV AX,22 ;Not all read
STC ;Set carry for error
READFIL_XIT:
RET
READ_FIL ENDP
;------------------------------------------------------------------------------
;Routine to handle input for a circular buffer
;
CBUF_INIT PROC FAR
MOV SI,0 ;Initialize SI
MOV DI,0 ;Initialize DI
MOV GAUGE,0 ; and # of bytes in buffer
MOV LAST,0 ; and last byte buffer
RET
CBUF_INIT ENDP
;------------------------------------------------------------------------------
;Routine to one byte into a circular buffer
;
CBUF_PUT PROC FAR
PUSH DX ;Save register
MOV DX,GAUGE ;Put V Guage in DX
MOV CBUF[DI],AL ;Put the byte into the buffer
INC DI ;Adjust pointer to next char
CMP DI,CBUF_SIZ ;Wrap it around?
JNE CBUF_PUT1 ;Skip if no wrap
MOV DI,0 ;Wraps back to zero
CBUF_PUT1:
INC DX ;Count the character
CMP DX,NEARFULL ;Too many characters?
JNE CBUF_PUT_XIT ;Skip if not
CALL COM_OFF ;Request to stop flow
CBUF_PUT_XIT:
POP DX ;Restore register
RET
CBUF_PUT ENDP
;------------------------------------------------------------------------------
;Routine to handle input to a circular buffer
;
CBUF_IN PROC FAR
CALL COM_INCK ;Check for a character
JZ CBUF_IN_XIT ;Good exit if none
AND AL,7FH ;Strip off parity bit
CMP AL,10 ;Check for <LF> (ASCII 10)
JNE CBUF_IN1 ;Skip if not <LF>
CMP LAST,13 ;Check for <CR> (ASCI 13)
JE CBUF_IN2 ;Skip if CR/LF
CBUF_IN1:
CALL CBUF_PUT ;Put byte into buffer
MOV LAST,AL ;Update last byte
CBUF_IN2:
CMP AL,13 ;Check for <CR>
JNE CBUF_IN3 ;Skip if not
;
;Insert LF if character was <CR>
PUSH AX ;Save the current character
MOV AL,10 ;<LF>
CALL CBUF_PUT ; goes into buffer
POP AX ;Restore current character
;
;Check for end of file
CBUF_IN3:
CMP AL,CTRL_Z ;Check for ^-Z (1AH)
JE CBUF_IN5 ;EOF is an exception
;
;Check for overflow
PUSH DX ;Save register
MOV DX,GAUGE
CMP DX,NEARFULL ;Overflow of characters?
JL CBUF_IN4 ;Skip if not
CALL COM_OFF ;Stop flow request
JMP CBUF_IN_XIT ;Good exit
CBUF_IN4: ;No overflow
CALL COM_ON ;Make sure flow is on
JMP CBUF_IN_XIT ;Good exit
CBUF_IN5: ;EOF exception handling
MOV AX,19 ;EOF exception code
STC ;Set carry for exception
JMP CBUF_IN_RET ;Return with exception
CBUF_IN_XIT:
POP DX
CLC ;Clear carry -- no exception
CBUF_IN_RET:
RET
CBUF_IN ENDP
;------------------------------------------------------------------------------
;Routine to flush a circular buffer
;
CBUF_CLR PROC FAR
PUSH DI ;Save registers
PUSH DX
PUSH CX
;
;Get the bytes from the buffer
MOV CX,GAUGE ;Get the count
JCXZ CBUF_CLR_XIT ;Check for empty
MOV DI,0 ;Initialize destination
;
;Loop to get all the bytes
CBUF_CLR1:
MOV AL,CBUF[SI] ;Get the character
INC SI ;Increment the pointer
CMP SI,CBUF_SIZ ;Wrap it?
JNE CBUF_CLR2 ;Skip if no wrap
MOV SI,0 ;Wrap the buffer pointer
CBUF_CLR2:
MOV LBUF[DI],AL ;Put the byte in linear buffer
INC DI
LOOP CBUF_CLR1 ;Loop until all bytes in LBUF
;
;Send the linear buffer to the disk
MOV CX,GAUGE ;This is the number of bytes
LEA DX,LBUF ;Here is where they are
CALL WRIT_FIL ;Send them out
MOV GAUGE,0 ;Set circular buffer empty
CBUF_CLR_XIT:
POP CX ;Restore registers
POP DX
POP DI
RET
CBUF_CLR ENDP
;------------------------------------------------------------------------------
;Routine to handle output from a circular buffer
;
CBUF_OUT PROC FAR
CMP GAUGE,BLK_SIZ ;Any characters?
JL CBUF_OUT_XIT ;If no, go
;
;Empty the buffer
CALL COM_OFF ;Hold the com line
CALL CBUF_CLR ;Clear the buffer
JC CBUF_OUT_RET ;Error?
CBUF_OUT_XIT:
CLC ;Clear carry -- no exception
CBUF_OUT_RET:
RET
CBUF_OUT ENDP
;------------------------------------------------------------------------------
;Routine to save a file from a communications line to disk
;
SAVE PROC FAR
;
;Set up return
PUSH DS ;Save for proper return
MOV AX,0 ;Point to beginning of segment
PUSH AX ; for the offset
;
;Set up segments
MOV DX,DS ;PSP was data segment
MOV AX,DATAS ;New data segment
MOV DS,AX ;Put in DS
MOV ES,AX ; and in ES
MOV WORD PTR DTA+2,DX ;Set the segment of the data
;
;Set up the file
LEA DX,NAME_BUF ;Point to the ASCIIZ buffer
CALL GET_SPEC ;Get file specifications
JC EXCEPTION ;Error?
LEA DX,NAME_BUF ;ASCIIZ buff had file specs
CALL MAKE_FIL ;Set up the file
JC EXCEPTION ;Error?
MOV BX,AX ;Get the file handle
;
;Set up the communications line
MOV DX,1 ;For COM1:
MOV AL,0BBH ;2400,E,8,1
CALL COM_INIT ;Initialize it
CALL COM_ON ; & turn it on
CALL CBUF_INIT ;Initialize the circular buffer
MOV DX,1 ;COM_2:
;
;Main loop for pulling in bytes
SAV_LOOP:
CALL CBUF_IN ;Check for input
JC EXCEPTION ;Error or EOF?
CALL CBUF_OUT ;Check to send it out
JC EXCEPTION ;Error?
JMP SAV_LOOP
EXCEPTION: ;Error/Exception handler
CMP AX,19 ;EOF?
JE SAV_1 ;If so, close it up & return
CALL EMSG_OUT ;Else report exception
JMP SAV_XIT ; and return
SAV_1: ;Normal return
CALL COM_OFF ;Com line off
CALL CBUF_CLR ;Clear the circular buffer
JC EXCEPTION ;Error?
CALL CLOS_FIL ;Close the file
JC EXCEPTION ;Error?
JMP SAV_XIT ;Exit
SAV_XIT:
CALL COM_ON ;Turn on com line
RET
SAVE ENDP
;------------------------------------------------------------------------------
CODES ENDS
;
END
;_____________________________________________________________________________
;>>>>> Physical EOF FILES.ASM <<<<<