From: SMTP%"RELAY-INFO-VAX@CRVAX.SRI.COM" 30-JUN-1993 18:03:48.29 To: EVERHART CC: Subj: Getting record sizes in Fortran From: dan@cafws2.eng.uci.edu (Dan Harkless) Subject: Getting record sizes in Fortran Nntp-Posting-Host: cafws2.eng.uci.edu Message-ID: <2C31BE3B.12339@news.service.uci.edu> X-Newsgroups: comp.os.vms Organization: University of California, Irvine Lines: 136 Date: 30 Jun 93 16:24:27 GMT To: Info-VAX@KL.SRI.COM X-Gateway-Source-Info: USENET Arrrgh! I'm at my wit's end! Can one of you VMS wizards help me out? Please? We're using a program here that was written by someone a long time ago that looks at a tape and tells you anytime the record size changes. Here's an example output: Tape mka500: should be mounted foreign Rec len changed. File: 4 Record: 1 Length: 5698 bytes Rec len changed. File: 8 Record: 2 Length: 5702 bytes Rec len changed. File: 12 Record: 3 Length: 5698 bytes Rec len changed. File: 24 Record: 6 Length: 5702 bytes Rec len changed. File: 28 Record: 7 Length: 5698 bytes The thing is, the File number shouldn't be equal to the record number times four. It should be equal to 1 until we reach an EOF, then 2, and so on. This program uses a VMS assembly "macro" that finds out the actual record size just read. It's after the call to this macro, 'getsiz', that the value of the variable file_num gets set to the record number left-shifted twice. There is a shift operation in the code for getsiz, but it's just shifting values in registers, and those registers don't get written out to memory, so I can see no good reason why this should be happening. Can someone maybe look at this to see if it looks okay? I've never actually seen VMS assembly before now, and don't have a manual, so I'm a bit unsure about a couple of instructions, for instance, what 'AP' refers to. This is really freaking me out because I've used getsiz with other programs as well; ones where the integrity of the output produced by the program is absolutely vital to research being done here! It really makes me queasy to think that getsiz might be just wantonly writing out values to memory. Here's the macro file, getsiz.mar: .TITLE Fortran callable subroutine to get record size ; This routine is callable from FORTRAN via the USEROPEN ; option on the OPEN statement. It saves the address of the RAB ; for use by GETSIZE. ; ; Apparently, the call is: CALL GETSIZ(IUNIT,ILEN) ; No, it's apparently ilen = getsiz(iunit) ; Also, assemble by: MACRO GETSIZ then LINK prog,GETSIZ FABOFF=4 ;FAB ADDRESS OFFSET RABOFF=8 ;RAB ADDRESS OFFSET UNOFFI=12 ;UNIT NUMBER ADDRESS OFFSET FOR GETSIZ_INIT UNOFF =4 ;UNIT NUMBER ADDRESS OFFSET FOR GETSIZ .ENTRY GETSIZ_INIT,^M $OPEN FAB=@FABOFF(AP) ;TRY TO OPEN THE FILE BLBC R0,20$ ;NO GO, GIVE UP $CONNECT RAB=@RABOFF(AP) ;TRY TO CONNECT TO THE FILE BLBC R0,20$ ;NO GO, GIVE UP MOVL @UNOFFI(AP),R2 ; GET LOGICAL UNIT NUMBER ASHL #2,R2,R3 ; SHIFT IT TWICE TO GET LONG WORD OFFSET MOVL RABOFF(AP),SAVRAB(R3) ;SAVE RAB ADDRESS IN TBL IND BY UNIT# 20$: RET ;RETURN SAVRAB: .BLKL 50 .ENTRY GETSIZ,^M MOVL @UNOFF(AP),R2 ; GET LOGICAL UNIT NUMBER ASHL #2,R2,R3 ; SHIFT IT TWICE TO GET LONG WORD OFFSET MOVL SAVRAB(R3),R2 ;GET ADDRESS OF RAB MOVZWL RAB$W_RSZ(R2),R0 ;GET RECORD SIZE JUST READ RET .END And here's the Fortran progam itself that calls getsiz: program Tapetest C Originally by : ? C Rewritten by : Dan Harkless C Last modified : 6-29-93 C Machine : CAFMV1 VAXstation 4000 VLC C Purpose : To examine tape files and record lengths C Instructions : To compile, type FOR TAPETEST then LINK TAPETEST,GETSIZ C Reference(s) : Needs getsiz.mar C History : First modifications on 7-2-91 C VVVVV This value can't be changed without rewriting getsiz.mar byte ia(24576) integer getsiz_init, getsiz external getsiz_init, getsiz integer rec, file_num, status integer*4 len, max character*80 DriveName status = cli$get_value('drive_name', DriveName) print *, ' ' write (6, 5) DriveName 5 format (' Tape ', A7, ' should be mounted foreign') print *, ' ' open(1,file='mka500:',form='unformatted',access='sequential', 1 recordtype='variable',status='old',useropen=getsiz_init) lenp = 0 max = 0 rec = 0 file_num = 1 6 read(1,err=10,end=20) ia 10 rec = rec + 1 len = getsiz(1) if (len .gt. max) then max = len end if if (len .ne. lenp) then write (6, 15) file_num, rec, len 15 format (' Rec len changed. File: ', I8, ' Record: ', I8, 1 ' Length: ', I6, ' bytes') end if lenp = len go to 6 20 if (rec.eq.0) then write(6,'('' EOT encountered.'')') rewind 1 stop end if write(6,'('' EOF encountered. file: '',i8,'' record: '',i8)') 1 file_num,rec print *, ' ' print *, 'Longest record was', max, ' bytes.' print *, ' ' file_num = file_num + 1 rec = 0 goto 6 end Thank you for any help you can provide, including suggestions of more reliable methods to determine record sizes of tapes being read. ---------------------------------------- | Dan Harkless | | University of California, Irvine | | Department of Mechanical Engineering | | dan@cafws1.eng.uci.edu | ----------------------------------------