.TITLE BLOCK_IO_UTILITY .IDENT /V01.0/ ;****************************************************************************** ; ; This set of subroutines is designed to facilitate of use of block ; I/O in any file of any type. It uses three RMS data structures; ; the FAB, RAB, and NAM. The subroutines use the VAX standard calling ; conventions. ; ;***************************************************************************** ; .PSECT DATA, NOEXE, NOWRT ; $FABDEF ; Define FAB symbols $RABDEF ; Define RAB symbols $NAMDEF ; Define NAM symbols $RMSDEF ; Define RMS symbols ; FAB: $FAB FAC = ,- ; Open for block I/O DNM = <.TXT> ; Default extension ; RAB: $RAB ROP = ,- ; Open for block I/O BKT = 1,- ; first virtual address RSZ = 512,- ; Read buffer of 512 bytes USZ = 512 ; Write buffer of 512 bytes ; NAM: $NAM ; Name block ; ; .PSECT CODE, EXE, NOWRT ; ;****************************************************************************** ; ; This subroutine initializes user supplied buffers as a FAB, RAB, ; and NAM. The subroutine is called as follows: ; ; call BIO_INIT (fab_addr, rab_addr, nam_addr) ; ; fab_addr = address of the FAB buffer ; rab_addr = address of the RAB buffer ; nam_addr = address of the NAM buffer ; ;***************************************************************************** ; ; BIO_INIT:: .WORD ^M ; MOVL 4(AP), R2 ; Save address of FAB CLRL R3 ; Clear loop counter ; FAB_LOOP: MOVL FAB(R3),(R2)+ ; move longword to FAB INCL R3 ; Add 4 to R3 INCL R3 INCL R3 INCL R3 CMPL R3, #FAB$C_BLN ; Check for end of loop BLSS FAB_LOOP ; MOVL 8(AP), R2 ; Save address of RAB CLRL R3 ; Clear loop counter ; RAB_LOOP: MOVL RAB(R3),(R2)+ ; move longword to RAB INCL R3 ; Add 4 to R3 INCL R3 INCL R3 INCL R3 CMPL R3, #RAB$C_BLN ; Check for end of loop BLSS RAB_LOOP ; MOVL 12(AP), R2 ; Save address of NAM CLRL R3 ; Clear loop counter ; NAM_LOOP: MOVL NAM(R3),(R2)+ ; move longword to NAM INCL R3 ; Add 4 to R3 INCL R3 INCL R3 INCL R3 CMPL R3, #NAM$C_BLN ; Check for end of loop BLSS NAM_LOOP ; RET ; ; ;****************************************************************************** ; ; This subroutine opens an existing file for block I/O operations ; only. It is called as follows: ; ; ret_status = BIO_OPEN (fab_addr, rab_addr, nam_addr, file_descr) ; ; fab_addr = address of the FAB buffer ; rab_addr = address of the RAB buffer ; nam_addr = address of the NAM buffer ; file_descr = address of the filename descriptor ; ; The ret_status returns the RMS return code. ; ;****************************************************************************** ; BIO_OPEN:: .WORD ^M ; MOVL AP, R3 ; Save Argument pointer MOVL 16(R3), R2 ; R2 contains address of descr. ; $FAB_STORE FAB = @4(R3),- ; 1st argument address FNA = @4(R2),- ; Address of filename string FNS = (R2),- ; Filename length NAM = @12(R3) ; Address of name block ; $NAM_STORE NAM = @12(R3),- ; 4th argument address ESA = @4(R2),- ; Address of filename string ESS = (R2) ; Filename length ; $RAB_STORE RAB = @8(R3),- ; 2nd argument address FAB = @4(R3) ; Address of FAB ; $OPEN FAB = @4(R3) ; Address of FAB BLBC R0, OPEN_ERROR ; Branch on error ; $CONNECT RAB = @8(R3) ; Address of RAB BLBC R0, OPEN_ERROR ; Branch on error ; RET ; Return ; OPEN_ERROR: RET ; ; ; ;****************************************************************************** ; ; This subroutine opens an new file for block I/O operations only. ; It is called as follows: ; ; ret_status = BIO_CREATE (fab_addr, rab_addr, nam_addr, file_descr) ; ; fab_addr = address of the FAB buffer ; rab_addr = address of the RAB buffer ; nam_addr = address of the NAM buffer ; file_descr = address of the filename descriptor ; ; The ret_status returns the RMS return code. ; ;****************************************************************************** ; BIO_CREATE:: .WORD ^M ; MOVL 4(AP), R3 ; Save FAB address CLRW FAB$W_IFI(R3) ; Clear IFI field CLRL FAB$L_SDC(R3) ; Clear SDC field CLRL FAB$L_STS(R3) ; Clear STS field CLRL FAB$L_STV(R3) ; Clear STV field ; MOVL 8(AP), R3 CLRW RAB$W_ISI(R3) ; Clear IFI field CLRL RAB$L_STS(R3) ; Clear STS field CLRL RAB$L_STV(R3) ; Clear STV field CLRW RAB$W_RFA(R3) ; Clear 3 words of RFA field INCL R3 CLRW RAB$W_RFA(R3) INCL R3 CLRW RAB$W_RFA(R3) ; MOVL AP, R3 ; Save Argument pointer MOVL 16(R3), R2 ; R2 contains address of descr. ; $FAB_STORE FAB = @4(R3),- ; 1st argument address FNA = @4(R2),- ; Address of filename string FNS = (R2),- ; Filename length NAM = @12(R3) ; Address of name block ; $NAM_STORE NAM = @12(R3),- ; 4th argument address ESA = @4(R2),- ; Address of filename string ESS = (R2) ; Filename length ; $RAB_STORE RAB = @8(R3),- ; 2nd argument address FAB = @4(R3) ; Address of FAB ; $CREATE FAB = @4(R3) ; Address of FAB BLBC R0, CREATE_ERROR ; Branch on error ; $CONNECT RAB = @8(R3) ; Address of RAB BLBC R0, CREATE_ERROR ; Branch on error ; RET ; Return ; ; CREATE_ERROR: RET ; On error return (R0=status) ; ; ; ; ;****************************************************************************** ; ; This subroutine reads one 512 byte block at the specified virtual ; block address. The file must already have been opened using either ; BIO_OPEN, or BIO_CREATE. The format is as follows. ; ; ret_status = BIO_READ (rab_addr, vir_blk, buf_addr) ; ; rab_addr = address of the RAB for this open file ; vir_blk = the virtual block number to be read ; buf_addr = address of a 512 user buffer to receive data ; ; The ret_status is for RMS return codes. ; ;****************************************************************************** ; ; BIO_READ:: .WORD ^M<> ; $RAB_STORE RAB = @4(AP),- ; RAB Address BKT = 8(AP),- ; Virtual block number UBF = @12(AP) ; Users buffer address ; $READ RAB = @4(AP) BLBC R0, READ_ERROR ; RET ; READ_ERROR: RET ; ; ; ; ;****************************************************************************** ; ; This subroutine writes one 512 byte block at the specified virtual ; block address. The file must already have been opened using either ; BIO_OPEN, or BIO_CREATE. The format is as follows. ; ; ret_status = BIO_WRITE (rab_addr, vir_blk, buf_addr) ; ; rab_addr = address of the RAB for this open file ; vir_blk = the virtual block number to be written ; buf_addr = address of a 512 user buffer to supply data ; ; The ret_status is for RMS return codes. ; ;****************************************************************************** ; ; BIO_WRITE:: .WORD ^M<> ; $RAB_STORE RAB = @4(AP),- ; RAB Address BKT = 8(AP),- ; Virtual block number RBF = @12(AP) ; Users buffer address ; $WRITE RAB = @4(AP) BLBC R0, WRITE_ERROR ; RET ; WRITE_ERROR: RET ; ; ;****************************************************************************** ; ; This subroutine is for flushing all I/O buffers associated with ; the given RAB. This is to assure that all modifications made to ; the file are reflected on the disk. ; ; The format is: ; ; ret_status = BIO_FLUSH (rab_addr) ; ; rab_addr = Address of the RAB for this file. ; ; ret_status = RMS return code ; ;****************************************************************************** ; ; BIO_FLUSH:: .WORD ^M<> ; $FLUSH RAB = @4(AP) BLBC R0, FLUSH_ERROR ; RET ; FLUSH_ERROR: RET ; ; ;****************************************************************************** ; ; This subroutine closes an already open file. The format is as follows. ; ; ret_status = BIO_CLOSE (fab_addr, rab_addr) ; ;****************************************************************************** ; ; BIO_CLOSE:: .WORD ^M<> ; ; $DISCONNECT RAB = @8(AP) ; Address of RAB BLBC R0, CLOSE_ERROR ; Branch on error ; $CLOSE FAB = @4(AP) ; Address of FAB BLBC R0, CLOSE_ERROR ; Branch on error ; RET ; Return ; CLOSE_ERROR: RET .END