.TITLE DISMMEM DISM32 Buffer Access Procedures .IDENT /01/ ; ; These procedures are FORTRAN-callable routines to extract values of ; various sizes from the buffer REC_BUF, no matter what their alignment, ; using byte-size indexing, rather than indexing in the size of the ; value wanted. The variable types supported are: ; BYTE (read into INTEGER*4, zero-extended) ; WORD (read into INTEGER*4, zero-extended) ; LONGWORD (read into INTEGER*4) ; QUADWORD (read into 2-element INTEGER*4 array) ; STRING (converted from zero-padded counted string to descriptor'd ; blank-padded string) ; WORD3 (3 consecutive bytes, read into INTEGER*4, zero-extended) ; ; All assume their arguments are passed by reference except for strings, ; which are passed by descriptor, (this is FORTRAN default). ; ; The exception DISM__INVBOFSET will be signaled (error level) and the amount ; of data available will be returned if the offset into the record buffer is ; greater than 511 (offsets start at 0). ; .PAGE .SBTTL External and FORTRAN Common Definitions ; .DISABLE GLOBAL ; .EXTRN DISM__INVBOFSET,STR$_TRU .EXTRN LIB$SIGNAL ; ; symbols for DISM32$MAIN .LIBRARY /SYS$LIBRARY:LIB/ $DYNDEF GLOBAL ; ; define the FORTRAN common ; .PSECT DSK_BUF,NOEXE,RD,WRT,PIC,OVR,GBL,SHR,NOVEC,LONG CUR_VBN: .BLKL 1 ; current VBN value REC_BUF: .BLKB 512 ; record buffer CUR_VA: .BLKL 1 ; current VA ; ; define the $CODE section ; .PSECT $CODE,EXE,RD,NOWRT,PIC,LCL,SHR,CON,REL,LONG ; .PAGE .SBTTL COPY_BYTE Byte Read Procedure ; .ENTRY COPY_BYTE,^M<> ; ; This procedure copies the Nth byte, zero-extended, into a longword pointed ; to by parameter #2. Parameter #1 is the address of the value N. The ; exception DISM__INVBOFSET is raised if the virtual page number of the address ; does not correspond to the virtual page number of the currently buffered ; page. ; 10$: MOVL @4(AP),R0 ; get value N, BICL3 #^C^X1FF,R0,R1 ; extract offset field, BICL2 #^X1FF,R0 ; extract virtual page number field, CMPL R0,CUR_VA ; check against current page number, BNEQ 20$ ; out of range, signal. MOVB REC_BUF[R1],@8(AP) ; get byte, RET ; exit. ; 20$: PUSHL @4(AP) ; push address, PUSHL #1 PUSHL #DISM__INVBOFSET ; push error code, CALLS #3,G^LIB$SIGNAL ; signal error, BRB 10$ ; try again if returned, ; .PAGE .SBTTL COPY_WORD Word Read Procedure ; .ENTRY COPY_WORD,^M<> ; ; This procedure calls COPY_BYTE twice to get a word. ; PUSHL @4(AP) ; push address to get, PUSHAW @8(AP) ; push address of word buffer, PUSHAL 4(SP) ; push address of address, CALLS #2,COPY_BYTE ; get the first byte, INCL (SP) ; move to the next address, MOVAW @8(AP),R0 ; get address of word buffer, PUSHAB 1(R0) ; push address of its second byte, PUSHAL 4(SP) ; push altered address of address, CALLS #2,COPY_BYTE ; get the second byte, RET ; return to caller. ; .PAGE .SBTTL COPY_WORD3 3-Byte Copy ; .ENTRY COPY_WORD3,^M<> ; ; This procedure is like COPY_WORD, except it calls COPY_BYTE three times, ; and fills the high byte of the longword destination with zero. ; CLRL @8(AP) ; pre-clear longword, PUSHL @4(AP) ; push address to get, PUSHAL @8(AP) ; push address of word buffer, PUSHAL 4(SP) ; push address of address, CALLS #2,COPY_BYTE ; get the first byte, INCL (SP) ; move to the next address, MOVAW @8(AP),R0 ; get address of word buffer, PUSHAB 1(R0) ; push address of its second byte, PUSHAL 4(SP) ; push altered address of address, CALLS #2,COPY_BYTE ; get the second byte, INCL (SP) ; move to the next address, MOVAW @8(AP),R0 ; get address of word buffer, PUSHAB 2(R0) ; push address of its third byte, PUSHAL 4(SP) ; push altered address of address, CALLS #2,COPY_BYTE ; get the third byte, RET ; return to caller. ; .PAGE .SBTTL COPY_LONG Longword Read Procedure ; .ENTRY COPY_LONG,^M<> ; ; This procedure is the same as COPY_WORD except the target is a longword. ; PUSHL @4(AP) ; push address to get, PUSHAW @8(AP) ; push address of word buffer, PUSHAL 4(SP) ; push address of address, CALLS #2,COPY_BYTE ; get the first byte, INCL (SP) ; move to the next address, MOVAW @8(AP),R0 ; get address of word buffer, PUSHAB 1(R0) ; push address of its second byte, PUSHAL 4(SP) ; push altered address of address, CALLS #2,COPY_BYTE ; get the second byte, INCL (SP) ; move to the next address, MOVAW @8(AP),R0 ; get address of word buffer, PUSHAB 2(R0) ; push address of its third byte, PUSHAL 4(SP) ; push altered address of address, CALLS #2,COPY_BYTE ; get the third byte, INCL (SP) ; move to the next address, MOVAW @8(AP),R0 ; get address of word buffer, PUSHAB 3(R0) ; push address of its fourth byte, PUSHAL 4(SP) ; push altered address of address, CALLS #2,COPY_BYTE ; get the fourth byte, RET ; return to caller. ; .PAGE .SBTTL COPY_QUAD Quadword Read Procedure ; .ENTRY COPY_QUAD,^M ; ; This procedure is the same as COPY_WORD except for the size of the target. ; PUSHL @4(AP) ; push address to get, PUSHAW @8(AP) ; push address of word buffer, PUSHAL 4(SP) ; push address of address, CALLS #2,COPY_BYTE ; get the first byte, MOVL #1,R2 ; clear loop index, 10$: INCL (SP) ; move to the next address, MOVAW @8(AP),R0 ; get address of word buffer, PUSHAB (R0)[R2] ; push address of next byte, PUSHAL 4(SP) ; push altered address of address, CALLS #2,COPY_BYTE ; get the next byte, AOBLEQ #7,R2,10$ ; go around again, RET ; return to caller. ; .PAGE .SBTTL COPY_STR Counted String Read Procedure ; .ENTRY COPY_STR,^M ; ; This procedure copies a counted string from the buffer into a fixed ; descriptor-specified string, padding with blanks or truncating as ; necessary. Truncation is signaled by the warning signal STR$_TRU. ; CLRQ -(SP) ; clear two storage locations on stack, MOVL @4(AP),-4(FP) ; store address parameter in second one, PUSHAL (SP) ; pass it, PUSHAL -4(FP) ; pass address parameter, CALLS #2,COPY_BYTE ; get counted string length, MOVL (SP)+,R2 ; put it in R2, CMPB (AP),#2 ; test if 3rd argument supplied, BLEQU 5$ ; no, don't get fancy. MOVW R2,@12(AP) ; yes, pass length back to caller. 5$: MOVAL @8(AP),R3 ; get address of string descriptor, MOVAL @4(R3),R5 ; get address of string buffer, CMPW R2,(R3) ; test if passed string is long enough. BLEQ 30$ ; yes, go ahead and do it, MOVZWL (R3),R2 ; no, so truncate string, PUSHL #STR$_TRU ; after warning user, CALLS #1,G^LIB$SIGNAL 30$: CLRL R4 ; set up R4 as a DO loop index, 31$: CLRL -(SP) ; clear a stack longword, PUSHAB (R5)[R4] ; get the next byte into the string, INCL -4(FP) ; using updated address parameter (MUST BE R/W), PUSHAL -4(FP) CALLS #2,COPY_BYTE AOBLSS R2,R4,31$ ; loop until entire string is transferred, CMPW R2,(R3) ; test if entire user string was filled, BEQL 40$ ; yes, just exit. ADDL2 R4,R5 ; no, pad remainder of string with spaces, SUBW3 R2,(R3),R2 MOVC5 #0,(SP),#^A/ /,R2,(R5) 40$: MOVL #1,R0 ; exit successfully. RET ; .END