home *** CD-ROM | disk | FTP | other *** search
- 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 <<<<<