!SQDASM19S: Modified 29/June/83 ! ! * Changed CHANGESM - corrects EMAS 2900 fault number 157, also ! has been substantially rewritten. ! ! AGRK !SQDASM18S: Modified 16/March/83 ! ! * Converted to IMP80 and SOAPed ! * Use of %alias to obviate need to change entry names and reference ! status after compilation (magio,openda,closeda,opensq,closesq) ! ! RDE (UKC) !SQDASM17S: Modified 6/December/82 ! ! * Changed OPTHEADER - efficiency only ! * Changed FORTRANDF - now accepts calls from NEW FILE OP to open a ! direct-access file for FORTRAN77 ! ! AGRK recordformat rf(integer conad,filetype,datastart,dataend) recordformat frf(integer conad,filetype,datastart,dataend,size,rup,eep,apf, c users,arch, string (6) tran, string (8) date,time, integer count, c spare1,spare2) recordformat fdf(integer link,dsnum, byteinteger status,access route, c valid action,cur state, byteinteger mode of use,mode,file org,dev class, c byteinteger rec type,flags,lm,rm, integer asvar,arec,recsize,minrec, c maxrec,maxsize,routeccy,conad,currec,cur,end,transfers,darecnum,cursize, c datastart, string (31) iden, string (8) device) systemintegermapspec comreg(integer n) systemroutinespec setpar(string (255) s) systemintegerfunctionspec parmap systemstringfunctionspec spar(integer n) systemintegerfunctionspec pstoi(string (255) s) systemroutinespec setfname(string (40) name) dynamicroutinespec magio alias "S#MAGIO" (integer afd,ep, integername flag) externalintegerfunctionspec uinfi(integer n) systemroutinespec finfo(string (31) file, integer mode, c record (frf) name r, integername flag) systemroutinespec extend(record (fdf) name f, integername flag) systemintegerfunctionspec open(integer afd,mode) systemintegerfunctionspec fdmap(integer chan) systemroutinespec signal(integer ep,pc,lnb, integername flag) systemroutinespec move(integer len,from,to) systemroutinespec psysmes(integer root,flag) systemroutinespec disconnect(string (31) s, integername f) systemroutinespec changefilesize(string (31) s, integer newsize, c integername flag) systemroutinespec fill(integer l,f,p) systemintegerfunctionspec close(integer i) systemroutinespec connect(string (31) file, integer mode,hole,protect, c record (rf) name r, integername flag) recordformat dahf(integer dataend,datastart,size,filetype,date,time,format, c records) constantinteger ssfformat= 1 constantinteger ssvformat= 2 constantinteger ssuformat= 3 constantinteger ssdatafiletype= 4 systemroutinespec outfile(string (31) s, integer len,maxlen,use, c integername conad,flag) !* !* integerfunction namel(integer dr0) !*********************************************************************** !* * !* This function decodes the top half of a descriptor passed by the * !* IMP %name parameter and returns the length of the entity passed in * !* bytes. Either the descriptor is scaled in which case the length is * !* decoded from the size code in the descriptor, or it is unscaled in * !* which case the length is held in the bound. * !* * !*********************************************************************** constantbyteintegerarray slen(3:7)= c 1,2,4,8,16; !LENGTHS FOR SCALED DESCRIPTORS if dr0 & x'02000000' = 0 thenresult = slen((dr0 >> 27) & 7) !SCALED - CODE IN SIZE result = dr0 & x'FFFFFF'; !UNSCALED - LENGTH IN BOUND end ; !OF NAMEL integerfunction optheader(integer blocksize) !CALCULATES THE OPTIMUM FILE HEADER SIZE FOR A DATA !FILE WITH A GIVEN BLOCK SIZE ! if blocksize <= 4096 thenstart ! ! Test if Record length is a multiple of 4096 (page size) ! if blocksize & (blocksize - 1) = 0 and blocksize >= 32 then c result = blocksize ! !Label Header Size used is the record length so ! long as it is a factor of 4096 and is also at ! least as large as the minimum header size finishelsestart if blocksize & 4095 = 0 thenresult = 4096 ! !Header size=4096 if 4096 is a !multiple of the record length finish result = 32; !in all other cases end ; !of OPT HEADER !*********************************************************************** !* * !* IMP SEQUENTIAL ACCESS ROUTINES * !* * !*********************************************************************** externalroutine opensq(integer chan) integer flag,afd record (fdf) name f ! SSOPENUSED = 1 flag = 0 unless 0 < chan <= 99 then flag = 164 and ->err !INVALID CHANNEL afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_status # 0 then flag = 176 and ->err !ALREADY OPEN f_link = uinfi(12); !FDLEVEL - TO CAUSE AUTO-CLOSE f_status = 2; !PARTLY OPEN - COMPLETED BY READSQ OR WRITESQ err: if flag # 0 then psysmes( - 49,flag) end ; !OF OPENSQ externalroutine closesq(integer chan) integer flag,afd flag = 0 unless 0 < chan <= 99 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED flag = close(afd) err: if flag # 0 then psysmes( - 50,flag) end ; !OF CLOSESQ owninteger holdlengthsq externalroutine writesq(integer chan,sdr0,sdr1,edr0,edr1) record (dahf) name head record (fdf) name f integer afd,start,len,flag,irgap flag = 0 unless 1 <= chan <= 80 or chan = 96 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_status = 0 then flag = 301 and ->err; !NOT OPEN if f_status = 2 start ; !OPENED BY OPENSQ - NOW COMPLETE THE OPEN f_modeofuse = 2; !SET MODE OF USE TO SQ flag = open(afd,2); !OPEN FOR WRITING ->err if flag # 0 if f_modeofuse # 2 then flag = 267 and setfname(f_iden) and ->err if f_accessroute # 5 start ; !NOT FOR MAG TAPE head == record(f_conad) head_filetype = ssdatafiletype head_format = (f_maxrec << 16 ! f_rectype) head_records = 0 finish finishelsestart ; !ALREADY FULLY OPEN if f_modeofuse # 2 or f_validaction & 2 = 0 then flag = 266 and ->err !INCONSISTENT FILE USE finish !NOW OPEN CORRECTLY - CHECK ADDRESSES start = sdr1 len = edr1 - sdr1 + namel(edr0); !TOTAL LENGTH OF REQUEST if len < 0 then flag = 177 and ->err; !ADDRESSES INSIDE OUT if f_rectype = ssfformat start ; !FIXED FORMAT if len # f_minrec then flag = 161 and ->err !WRONG RECORD LENGTH irgap = 0; !NO INTER RECORD GAP finishelsestart if len > f_maxrec then flag = 161 and ->err !WRONG RECORD LENGTH irgap = 2 finish if f_accessroute = 5 start ; !MAGNETIC TAPE move(len,start,f_arec); !MOVE DATA TO IO BUFFER f_recsize = len magio(afd,3,flag) ->err finish while f_cur + len + irgap > f_end cycle extend(f,flag) if flag # 0 start if flag = 1 then flag = 169; !OUTPUT EXCEEDED ->err finish repeat move(len,start,f_cur + irgap) if irgap # 0 start ; !PUT IN REC SEPARATOR len = len + 2 byteinteger(f_cur) <- len >> 8 byteinteger(f_cur + 1) <- len finish f_cur = f_cur + len f_transfers = f_transfers + 1 err: if flag # 0 then psysmes( - 83,flag); !PRINT MESSAGE AND STOP end ; !OF WRITESQ externalroutine readlsq(integer chan,sdr0,sdr1,edr0,edr1, c integername reqlen) record (fdf) name f integer afd,start,len,irgap,flag flag = 0 unless 1 <= chan <= 80 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_status = 0 then flag = 301 and ->err; !NOT OPEN if f_status = 2 start ; !OPENED BY OPENSQ - NOW COMPLETE flag = open(afd,1); !OPEN FOR READING ->err if flag # 0 unless f_rectype = ssfformat or f_rectype = ssvformat or c (f_rectype = ssuformat and f_accessroute = 5) then c flag = 267 and setfname(f_iden) and ->err !INVALID FILETYPE UNLESS F,V, OR (U IF MAG TAPE) f_modeofuse = 2; !SEQUENTIAL USE finishelsestart ; !ALREADY FULLY OPEN if f_modeofuse # 2 or f_validaction & 2 # 0 then flag = 266 and ->err !INCONSISTENT FILE USE finish !NOW OPEN CORRECTLY start = sdr1 reqlen = edr1 - sdr1 + namel(sdr0) if reqlen < 0 then flag = 177 and ->err; !ADDRESSES INSIDE-OUT if f_accessroute = 5 start ; !MAGNETIC TAPE magio(afd,2,flag) if flag # 0 start if flag = 153 then flag = 0 and reqlen = 0 !INPUT ENDED ->err finish if f_recsize < reqlen then reqlen = f_recsize !RECORD SHORTER THAN REQUESTED move(reqlen,f_arec,start) ->err finish if f_cur >= f_end then reqlen = 0 and ->err !INPUT ENDED if f_rectype = ssfformat start ; !FIXED FORMAT if reqlen > f_minrec then reqlen = f_minrec !RECORD SHORTER THAN REQUEST len = f_minrec; !THE ACTUAL RECORD LENGTH irgap = 0 finishelsestart ; !VARIABLE RECORD FORMAT len = (byteinteger(f_cur) << 8) ! byteinteger(f_cur + 1) - 2 !LENGTH OF DATA IN RECORD if reqlen > len then reqlen = len !RECORD SHORTER THAN REQUESTED LENGTH irgap = 2 finish move(reqlen,f_cur + irgap,start); !MOVE DATA TO PROGRAM AREA f_cur = f_cur + irgap + len err: if flag # 0 then psysmes( - 84,flag) end ; !OF READLSQ externalroutine readsq(integer chan,sdr0,sdr1,edr0,edr1) integer len,flag readlsq(chan,sdr0,sdr1,edr0,edr1,len) holdlengthsq = len if len = 0 then signal(2,140,0,flag); !SIGNAL INPUT ENDED end ; !OF READSQ externalintegerfunction lengthsq result = holdlengthsq end ; !OF LENGTHSQ !*********************************************************************** !* * !* ALGOL SEQUENTIAL ACCESS ROUTINES * !* * !*********************************************************************** systemroutine opensq1 alias "S#OPENSQ" (integer chan) !SQ ROUTINE FOR ALGOL integer flag,afd record (fdf) name f ! SSOPENUSED = 1 flag = 0 unless 0 < chan <= 99 then flag = 164 and ->err !INVALID CHANNEL afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_status # 0 then flag = 176 and ->err !ALREADY OPEN f_link = uinfi(12); !FDLEVEL - TO CAUSE AUTO-CLOSE f_status = 2; !PARTLY OPEN - COMPLETED BY READSQ OR WRITESQ err: if flag # 0 then psysmes( - 49,flag) end ; !OF OPENSQ systemroutine closesq1 alias "S#CLOSESQ" (integer chan) !SQ ROUTINE FOR ALGOL integer flag,afd flag = 0 unless 0 < chan <= 99 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED flag = close(afd) err: if flag # 0 then psysmes( - 50,flag) end ; !OF CLOSESQ systemroutine rwndsq(integer chan) !SQ ROUTINE FOR ALGOL - DOES CLOSE+OPEN integer flag,afd record (fdf) name f flag = 0 unless 0 < chan <= 99 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED flag = close(afd) if flag # 0 then ->err f == record(afd) f_link = uinfi(12); !FDLEVEL - TO CAUSE AUTOCLOSE f_status = 2; !PARTLY OPEN - COMPLETED BY READSQ OR WRITESQ err: if flag # 0 then psysmes( - 91,flag) end ; !OF RWNDSQ systemroutine putsq(integer chan,dr0,dr1, longinteger dopevdesc) !SQ ROUTINE FOR ALGOL, EQUIVALENT TO WRITESQ !DOPE VECTOR DESCRIPTOR IS NOT USED record (dahf) name head record (fdf) name f integer afd,start,len,flag,irgap flag = 0 unless 1 <= chan <= 80 or chan = 96 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_status = 0 then flag = 301 and ->err; !NOT OPEN if f_status = 2 start ; !OPENED BY OPENSQ - NOW COMPLETE THE OPEN f_modeofuse = 2; !SET MODE OF USE TO SQ flag = open(afd,2); !OPEN FOR WRITING ->err if flag # 0 if f_modeofuse # 2 then flag = 267 and ->err head == record(f_conad) head_filetype = ssdatafiletype head_format = (f_maxrec << 16 ! f_rectype) head_records = 0 finishelsestart ; !ALREADY FULLY OPEN if f_modeofuse # 2 or f_validaction & 2 = 0 then flag = 266 and ->err !INCONSISTENT FILE USE finish start = dr1; !NOW OPEN, DECODE DESCRIPTOR len = namel(dr0) * (dr0 & x'FFFFFF') if f_rectype = ssfformat start ; !FIXED FORMAT if len # f_minrec then flag = 161 and ->err !WRONG RECORD LENGTH irgap = 0; !NO INTER RECORD GAP finishelsestart if len > f_maxrec then flag = 161 and ->err !WRONG RECORD LENGTH irgap = 2 finish if f_cur + len + irgap > f_end thenstart extend(f,flag) if flag # 0 then flag = 169 and ->err; !OUTPUT EXCEEDED finish move(len,start,f_cur + irgap) if irgap # 0 start ; !PUT IN REC SEPARATOR len = len + 2 byteinteger(f_cur) <- len >> 8 byteinteger(f_cur + 1) <- len finish f_cur = f_cur + len f_transfers = f_transfers + 1 err: if flag # 0 then psysmes( - 89,flag); !PRINT MESSAGE AND STOP end ; !OF PUTSQ systemroutine getsq(integer chan,dr0,dr1, longinteger dopevdesc) !SQ ROUTINE FOR ALGOL EQUIVALENT TO READSQ !DOPE VECTOR DESCRIPTOR IS NOT REQUIRED record (fdf) name f integer afd,start,len,irgap,flag,reqlen flag = 0 unless 1 <= chan <= 80 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_status = 0 then flag = 301 and ->err; !NOT OPEN if f_status = 2 start ; !OPENED BY OPENSQ - NOW COMPLETE flag = open(afd,1); !OPEN FOR READING ->err if flag # 0 if ssfformat # f_rectype # ssvformat then flag = 267 and ->err !INVALID FILETYPE f_modeofuse = 2; !SEQUENTIAL USE finishelsestart ; !ALREADY FULLY OPEN if f_modeofuse # 2 or f_validaction & 2 # 0 then flag = 266 and ->err !INCONSISTENT FILE USE finish !NOW OPEN CORRECTLY start = dr1 reqlen = namel(dr0) * (dr0 & x'FFFFFF') if f_cur >= f_end then signal(2,140,0,flag) !INPUT ENDED if f_rectype = ssfformat start ; !FIXED FORMAT if reqlen > f_minrec then reqlen = f_minrec; !RECORD SHORTER THAN REQUEST len = f_minrec; !THE ACTUAL RECORD LENGTH irgap = 0 finishelsestart ; !VARIABLE RECORD FORMAT len = (byteinteger(f_cur) << 8) ! byteinteger(f_cur + 1) - 2 !LENGTH OF DATA IN RECORD if reqlen > len then reqlen = len !RECORD SHORTER THAN REQUESTED LENGTH irgap = 2 finish move(reqlen,f_cur + irgap,start); !MOVE DATA TO PROGRAM AREA f_cur = f_cur + irgap + len holdlengthsq = reqlen err: if flag # 0 then psysmes( - 90,flag) end ; !OF GETSQ !*********************************************************************** !* * !* STORE MAPPING ROUTINES * !* * !*********************************************************************** externalroutine newsmfile(string (255) s) string (31) file,size integer isize,flag,conad,i record (dahf) name dah record (frf) fr setpar(s) if parmap # 3 then flag = 263 and ->err; !WRONG NO OF PARAMS file = spar(1) size = spar(2) finfo(file,0,fr,flag) if flag = 0 then flag = 219; !ALREADY EXISTS if flag # 218 then ->err; !218 MEANS DOES NOT EXIST - OK isize = pstoi(size) if isize <= 0 then setfname(size) and flag = 202 and ->err outfile(file,isize + 32,0,0,conad,flag) ->err if flag # 0 dah == record(conad) dah_dataend = isize + 32; !TOTAL SIZE dah_datastart = 32; !LENGTH OF HEADER dah_filetype = ssdatafiletype; !DATA FILE dah_format = ssuformat; !UNSTRUCTURED disconnect(file,i) err: comreg(24) = flag; !RETURN CODE if flag # 0 then psysmes(44,flag) end ; !OF NEWSMFILE externalintegerfunction smaddr(integer chan, integername len) integer flag,afd record (rf) rr record (fdf) name f ! SSOPENUSED = 1 !TO INDICATE OPEN USED unless 0 < chan <= 80 then flag = 223 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !CHAN NOT DEFINED f == record(afd) if f_status # 0 then flag = 265 and ->err !ALREADY OPEN if f_accessroute = 10 then flag = 294 and ->err !ILLEGAL USE OF .NULL connect(f_iden,3,0,0,rr,flag); !TRY AND CONNECT WRITE if flag = 0 start ; !CONNECTED IN WRITE MODE f_validaction = 3; !READ AND WRITE finishelsestart connect(f_iden,0,0,0,rr,flag); !TRY READ MODE ->err if flag # 0; ! STILL NO GOOD f_validaction = 1; !ONLY READING ALLOWED finish f_status = 3; !OPEN f_accessroute = 3; !MAPPED FILE f_link = uinfi(12); !FDLEVEL - TO CAUSE AUTO-CLOSE len = rr_dataend - rr_datastart result = rr_conad + rr_datastart err: psysmes( - 17,flag) end ; !OF SMADDR externalroutine opensm(integer chan,mode, integername ad,len) !MODE=0 DON'T CARE !MODE=1 READ ONLY !MODE=2 READ+WRITE !ADDRESS RETURNED THROUGH AD, DATALENGTH THROUGH LEN string (31) file,rest integer flag,afd record (frf) fr record (rf) rr record (fdf) name f unless 0 < chan <= 80 then flag = 223 and ->err !INVALID CHAN afd = fdmap(chan); !NOTE THAT THIS SETS SSOPENUSED IN BASEFILE TO ENSURE FILE !IS CLOSED ON THE WAY BACK TO COMMAND if afd = 0 then flag = 151 and ->err; !CHAN NOT DEFINED f == record(afd) if f_status # 0 then flag = 265 and ->err !ALREADY OPEN if f_accessroute = 10 then flag = 294 and ->err !ILLEGAL USE OF .NULL if mode & 2 = 2 then mode = 3; !ENSURE READ INCLUDED connect(f_iden,mode,0,0,rr,flag); !TRY AND CONNECT IN REQUESTED MODE if flag = 0 start ; !CONNECTED IN REQUESTED MODE unless f_iden - > file.("_").rest then file = f_iden finfo(file,0,fr,flag) if fr_apf & x'F0' # 0 then f_validaction = 3 else f_validaction = 1 f_status = 3; !OPEN f_accessroute = 3; !MAPPED FILE f_link = uinfi(12); !FDLEVEL - TO CAUSE AUTO-CLOSE len = rr_dataend - rr_datastart ad = rr_conad + rr_datastart finishelsestart ad = 0; !TO INDICATE FAILURE len = 0 return finish err: if flag # 0 then psysmes( - 17,flag) end ; !OF OPENSM externalroutine closesm(integer chan) integer flag,afd record (fdf) name f unless 0 < chan <= 80 then flag = 223 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_status = 0 then flag = 301 and ->err !CHANNEL NOT OPEN if f_accessroute # 3 then flag = 266 and ->err !INCONSISTENT USE flag = close(afd) err: if flag # 0 then psysmes( - 26,flag) end ; !OF CLOSESM Externalroutine CHANGESM (integer chan, newsize) ! ! !---------------------------------------------------------------------%C C Modified 29/June/83 C C This procedure did not update the Total File Size field C in the file header presumably because it assumed that C CHANGEFILESIZE would do it, and it doesnt. C C An explicit check now only allows character and data files. C C Also error 295, although detected, was never reported. C C AGRK C C !----------------------------------------------------------------------- record (fdf) name f {file definition table format} record (rf ) rr {CONNECT record format} string (31) file {copy of F_IDEN} integer flag integer maxsize {new maximum size of file} integer oldsize {old size of file taken from DATAEND} integer afd { address of file definition table for CHAN} unless 0 < chan <= 80 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_status # 0 then flag = 302 and -> err !FILE OPEN file = f_iden if newsize <= 0 then flag = 295 and -> err; !INVALID FILESIZE ! ! Connect the File (in write mode and in a 'suitable' hole) ! Connect (file, 3, newsize + 4096, 0, rr, flag); -> err if flag¬= 0 ! newsize + 4096 gets the file ! connected in a hole ! which should be large ! enough if rr_filetype¬= 3 {a character file} and c rr_filetype¬= 4 {a data file } thenstart ! {What use someone can make of the } Disconnect (file,flag) {ability to access a character } Setfname (file) {file as a store-map file escapes } flag= 267; !INVALID FILE TYPE {me right now, but we will let it } -> err {through. However all the other } {file types are definitely invalid} finish !Calculate new file sizes: ! newsize= integer(rr_conad+4) + newsize ; !increment newsize by header length maxsize= x'fffff000' & (newsize+4095); !calculate the maximum file length oldsize= integer(rr_conad ) ; ! remember current actual length !and update the file header: ! integer(rr_conad )= newsize; !update actual length of file integer(rr_conad+8)= maxsize; !update maximum length of file ! ! Tidy Up and Disconnect ! Fill (maxsize-newsize,rr_conad+newsize,0) if newsize<oldsize {zero out the hole in the last page} { if the file size has been made } { smaller } Disconnect (file,flag) if flag¬= 0 then -> err ! ! Finally Update the Physical File Size ! Changefilesize (file,newsize,flag) ! !It might be considered sailing alittle bit close to the wind !to update the file header before changing the physical file !size but it does save a Connect and a Disconnect. err: if flag¬= 0 then Psysmes (-33, flag) end ; !of CHANGESM !*********************************************************************** !* * !* FORTRAN DEFINE FILE * !* * !*********************************************************************** systemintegerfunction fortrandf(integer dsnum,numblocks,blksize,asvardescad) !*********************************************************************** !* * !* Called by FORTRAN statement DEFINE FILE. If channel is open ignore * !* call. Otherwise try and connect the file, first write, then read. * !* If it does not exist create a new one taking size from * !* NUMBLOCKS*BLKSIZE. If it does exist check that BLKSIZE agrees with * !* file and that NUMBLOCKS is not greater than in file. Extract info * !* about associated variable and store in file descriptor. * !* * !*********************************************************************** ! !Modified 6/December/82 ! !If ASVARDESCAD is zero then FORTRANDF will have been ! called from NEW FILE OP to open a file for direct ! -access for FORTRAN77. The file/channel will have ! been connected via a DEFINE command with the third ! parameter set to 'D'. ! record (fdf) name f record (dahf) name h record (rf) rr ! owninteger dummy f77 asvar= 0 ! DUMMY F77 ASVAR is a variable pointed at by a FORTRAN77 ! File Definition Table and which pretends to be an ! Associated Variable to fool OUTREC and INREC when ! they are handling Direct-Access requests. ! integer flag,afd,size,headr ! SSOPENUSED = 1 unless 1 <= dsnum <= 80 thenresult = 164 !INVALID CHAN afd = fdmap(dsnum) if afd = 0 thenresult = 151; !NOT DEFINED f == record(afd) if f_status # 0 thenresult = 0; !ALREADY OPEN - IGNORE CALL if f_accessroute = 10 thenresult = 294; !ILLEGAL USE OF .NULL f_validaction = 67; !READ,WRITE,SEEK BY DEFAULT f_modeofuse = 13; !FORTRAN DA !FIRST TRY AND CONNECT IN WRITE MODE connect(f_iden,3,0,0,rr,flag) if flag = 218 start ; !FILE DOES NOT EXIST ! if asvardescad = 0 thenstart ! ! Extract Record and File Sizes for a FORTRAN77 Open ! blksize = f_maxrec numblocks = (f_maxsize - 32) // blksize finish headr = optheader(blksize); !GET OPT FILE HEADER SIZE size = headr + (blksize * numblocks) outfile(f_iden,size,0,0,rr_conad,flag) !TRY AND CREATE if flag # 0 thenresult = flag h == record(rr_conad) h_dataend = size h_datastart = headr h_filetype = ssdatafiletype h_format = (blksize << 16) ! ssfformat; !FIXED FORMAT h_records = numblocks ->opened finishelsestart ; !FAILED TO CONNECT WRITE if flag # 0 start connect(f_iden,0,0,0,rr,flag) if flag # 0 thenresult = flag f_validaction = 65; !READ AND SEEK ONLY finish finish h == record(rr_conad) if asvardescad = 0 thenstart ; ! (FORTRAN77 specific) ! blksize = h_format >> 16 numblocks = (h_data end - h_data start) // blksize finish if (h_dataend - h_datastart) < (numblocks * blksize) or c h_filetype # ssdatafiletype or h_format & x'FF' # ssfformat then c result = 179 !INVALID FILE FOR DA if h_format >> 16 # blksize thenresult = 180 !WRONG RECORD LENGTH FOR DA opened: unless asvardescad = 0 thenstart ! ! Set the FORTE Associated Variable address ! if integer(asvardescad) >> 24 = x'58' then f_flags = f_flags ! 4 else c f_flags = f_flags & x'BF' !Test if the Associated Variable is an Integer*2 or Integer*4 ! f_asvar = integer(asvardescad + 4) finishelse f_asvar = addr(dummy f77 asvar) f_conad = rr_conad f_datastart = h_datastart; !HEADER MIGHT NOT BE 32 BYTES f_rectype = 1; !FIXED f_maxsize = h_records f_maxrec = blksize f_minrec = blksize f_recsize = blksize f_status = 3 f_link = uinfi(12); !FDLEVEL - TO CAUSE AUTO CLOSE f_curstate = 1 f_darecnum = 1; !ASSUME STARTS AT BLOCK 1 result = 0 end ; !OF FORTRANDF !*********************************************************************** !* * !* IMP DIRECT ACCESS ROUTINES * !* * !*********************************************************************** constantinteger recsize= 1024; !FIXED RECORD SIZE PROTEM externalroutine openda(integer chan) integer afd,flag record (rf) rr record (dahf) name h record (fdf) name f ! SSOPENUSED = 1 unless 1 <= chan <= 80 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_status # 0 then flag = 176 and ->err !ALREADY OPEN if f_accessroute = 10 then flag = 294 and ->err !ILLEGAL USE OF .NULL f_validaction = 3; !READ AND WRITE - DEFAULT f_modeofuse = 3; !DIRECT ACCESS !FIRST TRY AND CONNECT IN WRITE MODE connect(f_iden,3,0,0,rr,flag); !CONNECT IN WRITE MODE if flag = 218 start ; !FILE DOES NOT EXIST outfile(f_iden,f_maxsize,0,0,rr_conad,flag) !CREATE IT ->err if flag # 0 h == record(rr_conad) h_dataend = f_maxsize h_datastart = recsize; !TO GIVE ALIGNMENT h_filetype = ssdatafiletype h_format = (recsize << 16) ! 1; !F1024 h_records = (h_dataend - h_datastart) // recsize finishelsestart if flag # 0 start ; !FAILED TO CONNECT IN WRITE MODE connect(f_iden,0,0,0,rr,flag); !TRY IN READ MODE ->err if flag # 0 f_validaction = 1; !ONLY READ ALLOWED finish finish h == record(rr_conad) if h_filetype # ssdatafiletype or h_format # (recsize << 16) ! 1 then c flag = 267 and ->err !INVALID FILETYPE f_conad = rr_conad f_transfers = h_records f_status = 3 f_link = uinfi(12); !FDLEVEL - TO CAUSE AUTO CLOSE err: if flag # 0 then psysmes( - 79,flag) end ; !OF OPENDA externalroutine closeda(integer chan) integer afd,flag record (fdf) name f unless 1 <= chan <= 80 then flag = 164 and ->err !INVALID CHANNEL afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_modeofuse # 3 then flag = 171 and ->err !INVALID OPERATION ON FILE if f_status = 0 then flag = 301 and ->err !NOT OPEN flag = close(afd) err: if flag # 0 then psysmes( - 80,flag) end ; !OF CLOSEDA externalroutine writeda(integer chan, integername sect, integer sdr0, c sdr1,edr0,edr1) integer afd,start,len,flag,sectneeded record (fdf) name f flag = 0 unless 1 <= chan <= 80 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_status = 0 then flag = 301 and ->err !NOT OPEN if f_modeofuse # 3 then flag = 171 and ->err !INVALID USE !NOW CALCULATE START ADDRESS AND LENGTH start = sdr1; !ADDRESS PART OF FIRST DESCRIPTOR len = edr1 - sdr1 + namel(edr0) !LENGTH TO BE MOVED if len < 1 then flag = 177 and ->err; !ADDRESSES INSIDE-OUT sectneeded = (len + recsize - 1) // recsize; !NO OF SECTIONS INVOLVED unless 1 <= sect <= f_transfers - (sectneeded - 1) then flag = 158 and ->err !RECORD OUT OF RANGE move(len,start,f_conad + integer(f_conad + 4) + recsize * (sect - 1)) !MOVE IN THE DATA sect = sect + sectneeded - 1 err: if flag # 0 then psysmes( - 81,flag) end ; !OF WRITEDA externalroutine readda(integer chan, integername sect, integer sdr0,sdr1, c edr0,edr1) integer afd,start,len,flag,sectneeded record (fdf) name f flag = 0 unless 1 <= chan <= 80 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_status = 0 then flag = 301 and ->err !NOT OPEN if f_modeofuse # 3 then flag = 171 and ->err !INVALID USE !NOW CALCULATE START ADDRESS AND LENGTH start = sdr1; !ADDRESS PART OF FIRST DESCRIPTOR len = edr1 - sdr1 + namel(edr0) !LENGTH TO BE MOVED if len < 1 then flag = 177 and ->err; !ADDRESSES INSIDE-OUT sectneeded = (len + recsize - 1) // recsize; !NO OF SECTIONS INVOLVED unless 1 <= sect <= f_transfers - (sectneeded - 1) then flag = 158 and ->err !RECORD OUT OF RANGE move(len,f_conad + integer(f_conad + 4) + recsize * (sect - 1),start) !MOVE IN THE DATA sect = sect + sectneeded - 1 err: if flag # 0 then psysmes( - 82,flag) end ; !OF READDA !*********************************************************************** !* * !* ALGOL DIRECT ACCESS ROUTINES * !* * !*********************************************************************** systemroutine openda1 alias "S#OPENDA" (integer chan) !DA ROUTINE FOR ALGOL integer afd,flag record (rf) rr record (dahf) name h record (fdf) name f ! SSOPENUSED = 1 unless 1 <= chan <= 80 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_rectype # 1 then flag = 179 and ->err; !MUST BE FIXED if f_status # 0 then flag = 176 and ->err !ALREADY OPEN if f_accessroute = 10 then flag = 294 and ->err !ILLEGAL USE OF .NULL f_validaction = 3; !READ AND WRITE - DEFAULT f_modeofuse = 3; !DIRECT ACCESS !FIRST TRY AND CONNECT IN WRITE MODE connect(f_iden,3,0,0,rr,flag); !CONNECT IN WRITE MODE if flag = 218 start ; !FILE DOES NOT EXIST outfile(f_iden,f_maxsize,0,0,rr_conad,flag) !CREATE IT ->err if flag # 0 h == record(rr_conad) h_datastart = optheader(f_minrec); !GET OPT FILE HEADER SIZE h_filetype = ssdatafiletype h_format = (f_minrec << 16) ! 1; !FIXED h_records = (f_maxsize - h_datastart) // f_minrec h_dataend = h_datastart + h_records * f_minrec finishelsestart if flag # 0 start ; !FAILED TO CONNECT IN WRITE MODE connect(f_iden,0,0,0,rr,flag); !TRY IN READ MODE ->err if flag # 0 f_validaction = 1; !ONLY READ ALLOWED finish finish h == record(rr_conad) if h_filetype # ssdatafiletype or h_format # (f_minrec << 16) ! 1 then c flag = 267 and ->err !INVALID FILETYPE f_conad = rr_conad f_transfers = h_records f_status = 3 f_link = uinfi(12); !FDLEVEL - TO CAUSE AUTO CLOSE err: if flag # 0 then psysmes( - 79,flag) end ; !OF OPENDA systemroutine closeda1 alias "S#CLOSEDA" (integer chan) !DA ROUTINE FOR ALGOL integer afd,flag record (fdf) name f unless 1 <= chan <= 80 then flag = 164 and ->err !INVALID CHANNEL afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_modeofuse # 3 then flag = 171 and ->err !INVALID OPERATION ON FILE if f_status = 0 then flag = 301 and ->err !NOT OPEN flag = close(afd) err: if flag # 0 then psysmes( - 80,flag) end ; !OF CLOSEDA systemroutine putda(integer chan, integername sect, integer dr0,dr1, c longinteger dopevdesc) !DA ROUTINE FOR ALGOL EQUIVALENT TO WRITEDA !DOPE VECTOR DESCRIPTOR IS NOT USED integer afd,start,len,flag,sectneeded record (fdf) name f flag = 0 unless 1 <= chan <= 80 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_status = 0 then flag = 301 and ->err !NOT OPEN if f_modeofuse # 3 then flag = 171 and ->err !INVALID USE !NOW CALCULATE START ADDRESS AND LENGTH start = dr1; !ADDRESS PART OF FIRST DESCRIPTOR len = namel(dr0) * (dr0 & x'FFFFFF') !LENGTH TO BE MOVED sectneeded = (len + f_minrec - 1) // f_minrec; !NO OF SECTIONS INVOLVED unless 1 <= sect <= f_transfers - (sectneeded - 1) then flag = 158 and ->err !RECORD OUT OF RANGE move(len,start,f_conad + integer(f_conad + 4) + f_minrec * (sect - 1)) !MOVE IN THE DATA sect = sect + sectneeded err: if flag # 0 then psysmes( - 92,flag) end ; !OF PUTDA systemroutine getda(integer chan, integername sect, integer dr0,dr1, c longinteger dopevdesc) !DA ROUTINE FOR ALGOL, EQUIVALENT TO READDA !DOPE VECTOR DESCRIPTOR NOT USED integer afd,start,len,flag,sectneeded record (fdf) name f flag = 0 unless 1 <= chan <= 80 then flag = 164 and ->err !INVALID CHAN afd = fdmap(chan) if afd = 0 then flag = 151 and ->err; !NOT DEFINED f == record(afd) if f_status = 0 then flag = 301 and ->err !NOT OPEN if f_modeofuse # 3 then flag = 171 and ->err !INVALID USE !NOW CALCULATE START ADDRESS AND LENGTH start = dr1; !ADDRESS PART OF FIRST DESCRIPTOR len = namel(dr0) * (dr0 & x'FFFFFF') !LENGTH TO BE MOVED sectneeded = (len + f_minrec - 1) // f_minrec; !NO OF SECTIONS INVOLVED unless 1 <= sect <= f_transfers - (sectneeded - 1) then flag = 158 and ->err !RECORD OUT OF RANGE move(len,f_conad + integer(f_conad + 4) + f_minrec * (sect - 1),start) !MOVE IN THE DATA sect = sect + sectneeded err: if flag # 0 then psysmes( - 93,flag) end ; !OF GETDA endoffile