TITLE LNKFIO - SUBROUTINES TO DO ALL FILE I/O FOR LINK SUBTTL D.M.NIXON/DMN/JLd/JBC/JNG/PAH/DZN/PY/JBS 2-OCT-85 ;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1974,1984,1986. ALL RIGHTS RESERVED.. ; ; ;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE ;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER ;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY ;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ;TRANSFERRED. ; ; ;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ;CORPORATION. ; ;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. SEARCH LNKPAR,LNKLOW,MACTEN,UUOSYM,SCNMAC IFN TOPS20,< SEARCH MONSYM > SALL ENTRY LNKFIO EXTERN .TYOCH,LNKCOR,LNKLOG CUSTVR==0 ;CUSTOMER VERSION DECVER==6 ;DEC VERSION DECMVR==0 ;DEC MINOR VERSION DECEVR==2352 ;DEC EDIT VERSION SEGMENT LNKFIO: SUBTTL REVISION HISTORY ;START OF VERSION 1A ;65 TENEX SPEEDUPS ;START OF VERSION 2 ;135 ADD OVERLAY FACILITY ;136 FIX I.ALC BUG ON DELETE ;170 CHANGE IODATA MACRO FOR PLOT SWITCH ;221 DELETE DVREN. USE DVRNF. INSTEAD ;222 (12773) DO UPDATE MODE ENTER RIGHT FOR DEFAULT PATH ;START OF VERSION 2B ;240 FIX I/O TO UNASSIGNED CHAN IF /SAVE AND HIGH FILE ALREADY EXISTS ;245 REWORK DVLKP. & LKPERR ROUTINES TO BE MORE GENERAL ; ADD DVCEM. & DVSUP. (ROUTINE TO CHECK FOR SUPERSEDE) ;356 LABEL EDIT 240 ;370 FIX LNKINS ERROR DETECT ;400 Support SFD's on output files. ;START OF VERSION 2C ;501 Support SFD's on symbol input and overlay files. ;537 Don't destroy I.PPN in DVRNF. for /SAVE ;557 Clean up listing for release. ;START OF VERSION 3A ;560 Release on both TOPS-10 and TOPS-20 as LINK version 3A(560) ;START OF VERSION 4 ;604 Handle device NUL: correctly ;610 Handle output defaulting of ersatz devices correctly. ;610 Don't let libraries confuse DVSUP. ;731 SEARCH MACTEN,UUOSYM ;740 Add code to get F.VER SCAN block field into I/O blocks ; and ( if input file ) to set version number of all output files. ;765 Release on both TOPS-10 and TOPS-20 as LINK version 4(765) ;START OF VERSION 4A ;1105 Fix edit 740 to not destroy the path to the file if it includes SFDs. ;1122 Remove edit 740. ;1123 Use HRLI instead of HRL to load ENTER error flag. ;1174 Label and clean up all error messages. ;1202 Make LNKNED message be potentially editable after 1174. ;1217 Clean up the listings for release. ;1220 Release on both TOPS-10 and TOPS-20 as version 4A(1220). ;1230 Remember the path after fake ENTER in DVSUP.. ;1250 Clear DATE/TIME fields in DVUPD. if TOPS-20, to preserve seconds. ;START OF VERSION 5 ; 1221-1477 Maintanence edits ;1401 Handle overflow and EXE file in native mode on TOPS-20. ;1402 Handle REL files in native mode on TOPS-20. ;1406 Get the creation date and time into I.PRV for /MAP. ;1407 Make overlay files work again ( broken in 1401 ). ;1416 Put an ERJMP after each GTFDB in DVLKP.. ;1461 Don't do an OPENF JSYS for an .EXE file if xaddr program is loaded. ;START OF VERSION 5A ;1500-1677 Maintenance edits ; ;1500 Compute word size of file correctly if bytesize not 36 bits. ;1507 Correct typo in DVCLS. ;1511 Correct another typo in DVCLS. ;1513 Correct typo at DVDLF. ;1527 Save IO.CHN at DVVRG2 during DY.GET to avoid ?I-O to Unassigned Channel ;1530 Create temp string in DVLKP./DVUPD. on stack, DY area may be exhausted. ;1541 Close file when deleting it. ;1547 Fix all cases where .REL bytesize not 36 bits. ;2014 Fix NUL: so it can be used. ;2017 Use LN.FL as max size of ASCIZ filespecs. ;2026 Update copyrights and clean up listing. ;2034 Use .IODPR instead of .IODMP in DVOPN. on TOPS-20. ;2067 Fix 2014 for NUL:. Was POPJing to data. ;2101 Fix off-by-one loop in "DVDPB.". ;Start of version 6 ;2202 Remove FTFRK2 conditional. ;2247 Get a second JFN for EXE file. ;2301 Fix up errors for TOPS-20 native files. ;2352 Update copyright statement. SUBTTL HERE TO SETUP POINTER TO I/O DATA BLOCK ;CALLED BY ; PUSHJ P,DVCHN. ;RETURN ; T1 = POINTER ;EXPECTS I/O CHAN# IN IO.CHN DVCHN.::MOVE T1,IO.CHN ;GET CHAN# SKIPE T1,IO.PTR(T1) ;GET I/O BLOCK POPJ P, E$$INS::.ERR. (MS,0,V%L,L%F,S%F,INS,) ;[1174] ;HERE TO DO DEVCHR FOR DEVICE ;CALLED BY ; PUSHJ P,DVCHK.## ;USES T1-T2 ;EXPECTS I/O CHAN# IN IO.CHN ;SETS IO.CHR WITH DEVCHR OF I/O DEVICE DVCHK.::PUSHJ P,DVCHN. ;GET ADDRESS IN T1 MOVE T2,I.DEV(T1) ;GET DEVICE DEVCHR T2, ;SEE WHAT IT IS MOVEM T2,IO.CHR ;SAVE FOR POSTERITY JUMPE T2,E01NED ;[1174] NO SUCH DEVICE MOVEI T2,DV.M0 ;MODE BIT SKIPGE I.MOD(T1) ;TEST FOR SPECIAL CASE POPJ P, ;WILL SET READ MODE LATER LSH T2,@I.MOD(T1) ;MODE WE WANT AND T2,IO.CHR ;SEE IF WE CAN USE IT JUMPN T2,CPOPJ ;OK RETURN E$$IDM::PUSH P,IO.CHN ;[1174] SAVE CHAN .ERR. (I,0,V%L,L%F,S%F,IDM,) SUBTTL HERE TO DO OPEN FOR NEW DEVICE ;CALLED BY ; PUSHJ P,DVOPN.## ;USES T1-T2 ;EXPECTS CHAN # IN IO.CHN ;OPENS DEVICE AND SETS UP BUFFERS IF REQUIRED DVOPN.::PUSHJ P,DVCHN. ;GET I/O BLOCK IFN TOPS20,< MOVE T2,IO.CHN ;PEEK AT THE CHAN # CAIE T2,DC ;REL OR EXE FILE? JRST DVOP1 ;NO, LET PA1050 PRESIDE MOVE T2,I.MOD(T1) ;DUMP MODE? ( EXE PROCESSING ) CAIN T2,.IODPR ;[2034] JRST DVRET1 ;RETURN BUFFER FOR THIS CHANNEL SKIPE I.DVZ(T1) ;ALREADY HAVE THE BUFFERS NEEDED? JRST DVBUF1 ; YES JRST DVVRG1 ; NO DVOP1: > ;[1402] IFN TOPS20 MOVEI T2,I.MOD(T1) ;ADDRESS OF OPEN BLOCK HRLI T2,(OPEN) ;FORM INST IOR T2,I.CHN(T1) ;PUT IN CHAN XCT T2 ;DO OPEN JRST E01OFD ;[1174] FAILED ;HERE TO ALLOCATE SPACE FOR BUFFERS HRRZI T2,I.MOD(T1) ;POINT TO DATA BLOCK FOR OPEN DEVSIZ T2, ;GET BUFFER SIZE IFE TOPS20, IFN TOPS20, JUMPE T2,DVRET1 ;DUMP MODE HAS NO BUFFERS ;HERE TO FAKE IT IF NUMBER OF BUFFERS IS TOO SMALL MOVE T3,IO.CHN ;GET CHAN NUMBER IFE TOPS20,< CAIE T3,DC ;INPUT ONLY JRST DVNDC ;NO HLRZ T3,T2 ;GET NUMBER OF BUFFERS CAIGE T3,.IBR ;ENOUGH ALREADY HRLI T2,.IBR ;[1174] NO, USE TOPS-10 LINK DEFAULT DVNDC:>;END IFE TOPS20 CAMN T2,I.DVZ(T1) ;SEE IF SAME JRST DVBUF1 ;SET UP BUFFERS EXCH T2,I.DVZ(T1) ;SWAP NEW FOR OLD JUMPE T2,DVVRG1 ;NOTHING TO GIVE BACK PUSHJ P,DVRET2 ;RETURN OLD BUFFER SPACE JRST DVVRG. ;AND GET NEW ;HERE TO RETURN ALL SPACE USED BY CHAN I/O DATA BLOCK ;CALLED BY ; PUSHJ P,DVZAP. ;USES T1, T2, T3 ;EXPECTS CHAN# IN IO.CHN DVZAP.::PUSHJ P,DVRET. ;REMOVE BUFFERS MOVE T3,IO.CHN ;GET CHAN# HRRZ T1,IO.PTR(T3) ;GET PTR SETZM IO.PTR(T3) ;CLEAR IT MOVEI T2,LN.IO ;LENGTH PJRST DY.RET## ;RETURN ;HERE TO RETURN OLD BUFFER SPACE ;CALLED BY ; PUSHJ P,DVRET. ;USES T1, T2, T3 ;EXPECTS CHAN# IN IO.CHN DVRET.::PUSHJ P,DVCHN. ;GET POINTER TO I/O BLOCK DVRET1: MOVE T2,I.DVZ(T1) ;GET BUFSIZ WORD DVRET2: JUMPLE T2,CPOPJ ;DUMP OR UNKNOWN IFN TOPS20,< MOVE T3,IO.CHN ;PEEK AT CHAN # CAIN T3,DC ;REL OR EXE CHANNEL? JRST DVRET3 ;YES, HANDLE IT DIFFERENTLY > ;[1402] IFN TOPS20 HLRZ T3,T2 HRRZ T2,T2 IMULI T2,(T3) ;CALCULATE HOW MUCH MOVE T1,I.RNG(T1) ;FROM WHERE PJRST DY.RET## ;GIVE IT ALL BACK IFN TOPS20,< DVRET3: MOVE T1,I.RNG(T1) ;PICK UP BUFFER PAGE # LSH T1,9 ;MAKE IT AN ADDRESS PJRST DY.RET ;GIVE IT BACK > ;[1402] IFN TOPS20 ;HERE TO GET VIRGIN SPACE ;CALLED BY ; PUSHJ P,DVVRG. ;USES T1, T2 ;EXPECTS CHAN# IN I/O CHAN DVVRG.::PUSHJ P,DVCHN. ;GET I/O BLOCK DVVRG1: MOVE T2,IO.CHR ;GET DEVCHR BITS TXC T2,DV.TTA!DV.TTY;[1174] MUST BE CONTROLLING TTY: (NUL: ISN'T) TXCN T2,DV.TTA!DV.TTY;[1174] .. JRST DVTTY ;[1174] YES IFN TOPS20,< MOVE T2,IO.CHN ;PEEK AT CHANNEL # CAIN T2,DC ;REL OR EXE FILE? JRST DVVRG2 ;YES, HANDLE DIFFERENTLY > ;[1402] IFN TOPS20 MOVE T2,I.DVZ(T1) ;GET BACK DEVSIZ INFO HLRZ T1,T2 ;NUMBER OF BUFFERS HRRZ T2,T2 ;SIZE OF EACH IMULI T2,(T1) ;TOTAL SIZE REQUIRED PUSHJ P,DY.GET## ;FIND THE SPACE MOVE T2,T1 ;TEMP STORE MOVE T1,IO.CHN ;GET CHAN MOVE T1,IO.PTR(T1) ;GET DATA BLOCK MOVEM T2,I.RNG(T1) ;STORE START OF BUFFER JRST DVBUF1 ;ALLOCATE THE BUFFERS IFN TOPS20,< DVVRG2: MOVEI T2,LN.BF ;FIXED BUFFERSIZE MOVEM T2,I.DVZ(T1) ;SET IN I/O BLOCK ADDI T2,.IPS*2 ;ASK FOR A LITTLE MORE PUSH P,IO.CHN ;[1527] SAVE IN CASE PAGING STARTS PUSHJ P,DY.GET ;SO WE'RE SURE TO GET IT ALL POP P,IO.CHN ;[1527] RESTORE CHANNEL NUMBER MOVE T2,T1 ;TEMP STORE MOVE T1,IO.CHN ;GET CHAN MOVE T1,IO.PTR(T1) ;GET DATA BLOCK ADDI T2,.IPS ;SET TO NEXT PAGE IN BUFFER LSH T2,-9 ;MAKE IT A PAGE # MOVEM T2,I.RNG(T1) ; AND STORE IT. JRST DVBUF1 ; FAKE UP BUFFER HEADERS > ;[1402] END IFN TOPS20 ;HERE TO SET UP BUFFERS ;CALLED BY ; PUSHJ P,DVBUF. ;USES T1, T2 ;EXPECTS CHAN# IN IO.CHN DVBUF.::PUSHJ P,DVCHN. ;GET I/O DATA BLOCK DVBUF1: IFN TOPS20,< MOVE T2,IO.CHN ;PEEK AT CHAN # CAIN T2,DC ;REL OR EXE FILE? JRST DVBUF2 ;YES, DO IT DIFFERENTLY > ;[1402] IFN TOPS20 MOVE T2,I.RNG(T1) ;GET START OF AREA MOVEM T2,.JBFF ;SET FREE SPACE POINTER TO POINT TO IT HLRZ T2,I.DVZ(T1) ;GET NUMBER OF BUFFERS HLL T2,I.BUF(T1) ;GET OUTPUT BUFFER HEADER TLZE T2,-1 ;OUTPUT DEVICE? TLOA T2,(OUTBUF) ;YES, FORM OUTBUF UUO HRLI T2,(INBUF) ;FORM INBUF UUO IOR T2,I.CHN(T1) ;PUT IN CHAN# XCT T2 ;SETUP BUFFERS MOVE T2,.JBREL ;INCASE /HELP MOVEM T2,.JBFF POPJ P, IFN TOPS20,< DVBUF2: MOVE T2,I.RNG(T1) ;PICK UP PAGE# LSH T2,9 ;MAKE IT AN ADDRESS HRL T2,[POINT 36,0] ;MAKE IT A BYTE POINTER MOVE T3,I.BUF(T1) ;PICK UP BUFFER HEADER POINTER HRRM T2,0(T3) ;PUT START-OF-BUFFER IN HEADER MOVEM T2,1(T3) ;SET START OF BUFFER SETZM 2(T3) ;CURRENT BUFFER LENGTH POPJ P, ;RETURN > ;[1402] IFN TOPS20 DVTTY: SETZM I.RNG(T1) ;CLEAR BITS JUST INCASE SETZM I.DVZ(T1) POPJ P, ;WILL USE TTCALLS ;HERE TO READ FILE SPEC AND BUILD LOOKUP BLOCK ;CALLED BY ; PUSHJ P,DVINP.## ;USES T1-T3 DVINP.::MOVE P1,F.INZR ;MAKE SURE P1 IS SETUP MOVEI T2,LN.RIB-1 ;LENGTH OF LOOKUP BLOCK DATA MOVEM T2,RIBLEN ;INCASE NOT SET UP MOVE T2,F.MOD(P1) ;PRESERVE SCAN MODE BITS MOVEM T2,MDSCN MOVE T2,F.NAME(P1) ;NAME MOVEM T2,FNAM MOVE T2,F.EXT(P1) ;EXTENSION HLLZM T2,FEXT MOVE T2,F.DIR(P1) ;DIRECTORY MOVEM T2,UFDPPN IFN LN.DRB,< ;IF ALLOWED FOR SFD'S SKIPN F.DIR+2(P1) ;DO WE HAVE ANY? POPJ P, ;NO MOVEM T2,SFDDIR ;STORE PPN MOVEI T1,SFDARG ;GET PNTR MOVEM T1,UFDPPN ;AS PPN MOVE T1,[-LN.DRB,,SFDDIR+1] MOVEI T2,F.DIR+2(P1) ;ADDRESS OF DIRECTORY DVSFD: MOVE T3,(T2) ;GET NEXT SFD MOVEM T3,(T1) ;STORE EVEN IF ZERO JUMPE T3,CPOPJ ;EXIT WHEN ZERO FOUND ADDI T2,2 ;SCAN COUNTS IN 2'S AOBJN T1,DVSFD ;KEEP GOING > POPJ P, ;ROUTINE TO A LOOKUP ;CALLED BY ; PUSHJ P,DVLKP. ; ERROR RETURN ; NORMAL RETURN ; ;EXPECTS ; IO.CHN TO CONTAIN I/O CHANNEL (AND CHANNEL IS OPEN) ; IO.CHR TO CONTAIN THE DEVCHR UUO WORD ; ;RETURNS WITH THE LOOKUP DONE ACCORDING TO DEVICE TYPE DVLKP.::PUSHJ P,DVCHN. ;SET POINTER TO I/O BLOCK IFE TOPS20,< MOVE T2,I.CHN(T1) ;GCHAN # JUSTIFIED TO AC TLO T2,(LOOKUP) ;MAKE AN I/O INSTRUCTION MOVE T3,IO.CHR ;SEE WHAT IT WAS TXNN T3,DV.DSK ;SEE IF A F/S JRST NFSLKP ;NO HRRI T2,I.RIB(T1) ;GET ADDR OF LOOKUP BLOCK XCT T2 ;EXTENDED LOOKUP POPJ P, ;FAILURE, ERROR RETURN MOVE T2,IO.CHN ;NOW FIND WHERE FILE IS USING MOVEM T2,I.ARG(T1) ;PATH. UUO, SINCE MONITOR LIES MOVEI T2,I.PTH(T1) ;IF FILE IS IN AN SFD... MOVEM T2,I.PPN(T1) ;ALWAYS MAKE I.PPN POINT TO PATH HRLI T2,.PTMAX ;LENGTH OF PATH BLOCK PATH. T2, ;FIND IT SETZM I.PPN(T1) ;CAN'T, ASSUME DEFAULT PATH PJRST CPOPJ1 ;SUCCESS, NORMAL RETURN ;HERE FOR NON-FILE STRUCTURE LOOKUP NFSLKP: HRRI T2,I.NAM(T1) ;ADDR OF SHORT BLOCK XCT T2 ;SHORT LOOKUP POPJ P, ;ERROR RETURN PJRST CPOPJ1 ;NORMAL RETURN > ;[1402] IFE TOPS20 IFN TOPS20,< MOVEI T1,1(P) ;[1530] NOTE START OF FREE STACK ADJSP P,LN.FL ;[2017] GET SOME SPACE THERE PUSHJ P,DVTXT1 ;[1530] CREATE THE STRING MOVE T2,T1 ; AND NOTE BYTEPOINTER THERETO MOVE T1,[GJ%SHT!GJ%OLD] ; FILE MUST EXIST GTJFN% ; GET JFN JRST [ ADJSP P,-LN.FL ;[2017] JRST DVERR. ] ;[2301] FAILURE ADJSP P,-LN.FL ;[2017] THROW AWAY STRING MOVE T2,[BYTE (6)0(4).GSNRM] ; FILE BYTESIZE AND MODE IOR T2,[OF%RD] OPENF% ; OPEN THE FILE JRST DVERR. ;[2301] FAILURE MOVE T2,IO.CHN ; PICK UP CHANNEL AGAIN MOVEM T1,CHAN.JF(T2) ; STASH JFN AWAY ... CAIE T2,DC ; WAS IT OPEN OF REL FILE? PJRST CPOPJ1 ; NO, JUST RETURN PUSH P,T3 ;[2014] SET ASIDE T3 PUSH P,T1 ;[2014] SAVE THE JFN DVCHR% ;[2014] GET THE DEVICE CHARISTERICS ERJMP [POP P,T1 ;[2301] FAILED, RESTORE THE JFN POP P,T3 ;[2301] CLEAN UP THE STACK JRST DVERR.] ;[2301] PRETTY STRANGE DEVICE... POP P,T1 ;[2014] RESTORE THE JFN LDB T2,[POINTR T2,DV%TYP] ;[2014] GET THE DEVICE TYPE CAIN T2,.DVNUL ;[2014] IS IT THE NUL DEVICE? JRST [SETZB T2,RFLEN ;[2014] HAS NO LENGTH OR CREATION TIME JRST DVLKP3] ;[2067] REJOIN MAIN ROUTINE CAIE T2,.DVDSK ;[2301] IS IT A DISK? JRST [MOVEI T2,DESX8 ;[2301] NO, GET "NOT DISK" ERROR POP P,T3 ;[2301] CLEAN UP THE STACK JRST DVERR1] ;[2301] TAKE ERROR RETURN MOVE T2,[6,,.FBCRE] ;[1547] LOOK AT WRDS 5-12 OF FDB MOVEI T3,.FBCRE(P) ;[1547] PTR TO VERY TEMPORARY STORAGE ADJSP P,6 ;[1547] SET IT ASIDE GTFDB% ;[1547] GET FILE DATA BLOCK ERJMP [ ADJSP P,-6 ;[1547] RELEASE TEMP STORAGE POP P,T3 ;[1547] AND T3 JRST DVERR.] ;[2301] GET THE ERROR CODE MOVE T2,<.FBCRE-.FBCRE>(T3) ;[1547] PICK UP CREATION DATE MOVE T1,IO.CHN ;[1547] MOVE T1,IO.PTR(T1) ;[1547] SAVE THIS INFO MOVEM T2,I.PRV(T1) ;[1547] FOR THE MAP FILE ;[1547] Now compute RFLEN, length of .REL file MOVE T1,<.FBSIZ-.FBCRE>(T3) ;[1547] LDB T3,[POINT 6,<.FBBYV-.FBCRE>(T3),11] ;[1547] GET BYTESIZE DATA JUMPE T3,DVLKP2 ;[1547] BYTESIZE=WORD SIZE CAILE T3,^D18 ;[1547] IF GREATER THAN 18 JRST DVLKP2 ;[1547] BYTESIZE=WORD SIZE MOVEI T2,^D36 ;[1547] DIVIDE 36 IDIV T2,T3 ;[1547] BY THE BYTESIZE IDIV T1,T2 ;[1547] FILE SIZE IN WORDS SKIPE T2 ;[1547] EXTRA BYTES? AOS T1 ;[1547] YES, ONE MORE WORD DVLKP2: MOVEM T1,RFLEN ;[1547] STORE WORD COUNT ADJSP P,-6 ;[1547] RELEASE TEMP STORAGE DVLKP3: POP P,T3 ;[2067] AND AC PJRST CPOPJ1 ; AND RETURN > ;[1402] IFN TOPS20 ;HERE TO HANDLE OUTPUT FILE SPECS ;CALLED BY ;PUSHJ P,DVOUT.## ;XWD CHAN#, MODE ;DVOUT. CHECKS FOR DEVICE ALREADY OPEN ON THIS CHAN ;SETS UP DATA BLOCK AND RETURNS ;OPEN AND ENTER WILL BE DONE LATER DVOUT.::HLRZ T1,@(P) ;PICKUP CHAN NUMBER MOVEM T1,IO.CHN ;SAVE FOR DEFERED SWITCHES MOVEI T2,LN.IO ;LENGTH REQUIRED SKIPN T1,IO.PTR(T1) ;ALREADY SETUP? PUSHJ P,DY.GET## ;NO, GET SPACE MOVE T2,IO.CHN ;GET CHAN AGAIN HRROM T1,IO.PTR(T2) ;POINT TO DATA AREA ;-1 IN LEFT SIGNALS OPEN NOT YET DONE MOVE T3,T1 ;SAFER PLACE FOR POINTER HRRE T1,@(P) ;GET MODE MOVEM T1,I.MOD(T3) ;STORE MODE IN OPEN BLOCK AOS (P) ;PASS OVER IT MOVE T1,OBFTBL(T2) ;GET BUFFER HEADER HRLZM T1,I.BUF(T3) ;INTO OPEN BLOCK HLLZM T1,I.CHN(T3) ;CHAN# IN AC FIELD MOVE T1,F.MOD(P1) ;PRESERVE SCAN MOD WORD MOVEM T1,I.SCN(T3) MOVEI T1,LN.RIB-1 ;LENGTH OF EXTENDED ENTER MOVEM T1,I.RIB(T3) SKIPN T1,F.NAME(P1) ;FILE NAME MOVE T1,O.NAM MOVEM T1,I.NAM(T3) SKIPN T1,F.EXT(P1) ;EXTENSION MOVE T1,O.EXT ;DEFAULT MUST BE SETUP PRIOR TO THIS HLLZM T1,I.EXT(T3) SKIPN T1,F.PROT(P1) ;PROTECTION CODE MOVE T1,O.PROT DPB T1,[POINT 9,I.PRV(T3),8] ;STORE LOWER 9 BITS ;CONTINUED ON NEXT PAGE ;FALL IN FROM ABOVE TO DEFAULT OUTPUT PATH AND OUTPUT DEVICE. ;MUST REMEMBER THAT AN EXPLICIT ERSATZ DEVICE IS EXPLICITLY ;SPECIFYING BOTH A DEVICE AND A PATH, SO THE DEFAULT PATH ;(FROM [PATH]/DEFAULT:OUTPUT) SHOULD NOT BE APPLIED EVEN IF NO ;EXPLICIT PATH WAS GIVEN. SIMILARLY, A DEFAULT ERSATZ DEVICE ;(REL:/DEFAULT:OUTPUT) CAN ONLY BE APPLIED IF NEITHER DEVICE ;NOR PATH WERE EXPLICITLY GIVEN. MOVSI T2,(FX.DIR) ;SET UP FOR TEST TDNN T2,F.MOD(P1) ;WAS DIRECTORY SPECIFIED? JRST DVOUT1 ;MAYBE NOT. GO SEE. MOVE T4,F.DIR(P1) ;ONE WAS. GET IT. TLNN T4,-1 ;PROJECT SPECIFIED? HLL T4,MYPPN ;NO, ASSUME DEFAULT TRNN T4,-1 ;PROGRAMMER GIVEN? HRR T4,MYPPN ;NO, DEFAULT MOVEI T1,F.DIR(P1) ;POINT TO DIRECTORY WE'RE USING JRST DVOUT4 ;[610] AND GO CHECK SFD'S ;HERE WHEN FX.DIR IS OFF. EITHER NONE SPECIFIED OR IT'S [-]. DVOUT1: TDNE T2,F.MODM(P1) ;[610] WHICH IS IT? JRST DVOUT3 ;[610] IT'S [-]. DON'T USE DEFAULT. MOVE T1,[3,,T2] ;[610] NO PATH GIVEN EXPLICITLY, SEE IF MOVE T2,F.MOD(P1) ;[610] ONE GIVEN VIA AN ERSATZ DEVICE TXNN T2,FX.NDV ;[610] FIRST, SEE IF THERE WAS A DEVICE SKIPN T2,F.DEV(P1) ;[610] SHOULD BE, MAKE SURE JRST DVOUT2 ;[610] NO DEVICE! PATH. T1, ;[610] SEE IF EXPLICIT DEVICE IS ERSATZ SETZ T3, ;[610] PROBABLY NOT TXNN T3,PT.IPP ;[610] DEVICE ERSATZ? DVOUT2: SKIPA T1,[O.DIR] ;[610] NO, COPY PATH FROM DEFAULT DVOUT3: MOVEI T1,F.DIR(P1) ;[610] YES, USE EXPLICIT PATH GIVEN MOVE T4,(T1) ;GET UFD FOR OUTPUT DVOUT4: MOVE T3,IO.CHN ;[610] RESTORE POINTER TO I.XXX HRRZ T3,IO.PTR(T3) ;[610] POSSIBLY DESTROYED BY PATH UUO SKIPN 2(T1) ;[610] ANY SFD'S??? JRST [MOVEM T4,I.PPN(T3) ;NO, STORE PPN JRST DVOUT6] ;[610] AND GO DEFAULT DEVICE MOVEM T4,I.UFD(T3) ;THERE ARE..UFD GOES IN I.UFD MOVEI T2,I.PTH(T3) ;GET POINTER TO PATH BLOCK MOVEM T2,I.PPN(T3) ;AND PUT IT IN ENTER BLOCK DVOUT5: ADDI T1,2 ;[610] POINT TO NEXT SFD FROM SCAN SKIPN T2,(T1) ;IS THIS THE END? JRST DVOUT6 ;[610] YES, GO DEFAULT DEVICE ;NOTE THAT THIS IS THE ONLY ; EXIT FROM THIS LOOP, BECAUSE ; THERE WILL ALWAYS BE A ZERO ; AFTER THE LAST SFD. MOVEM T2,I.SFD(T3) ;NOT LAST SFD. STORE IT. AOJA T3,DVOUT5 ;[610] CHECK FOR MORE ;*** NOTE T3 MODIFIED HERE *** ;CONTINUED ON NEXT PAGE ;NOW TO DEFAULT THE DEVICE. IF THE DEFAULT DEVICE IS ERSATZ, ;WE CAN ONLY USE IT IF EXPLICIT SPEC CONTAINED NEITHER DEVICE ;NOR PATH. NOTE THAT DEVICE DEFAULTING MUST TAKE PLACE AFTER PATH ;DEFAULTING TO AVOID CONFUSING THE DEFAULT AND EXPLICIT DEVICES ;IN PATH DEFAULTING CODE. DVOUT6: MOVE T2,F.MOD(P1) ;[610] SEE IF USER GAVE EXPLICIT DEVICE TXNN T2,FX.NDV ;[610] .. SKIPN T2,F.DEV(P1) ;[610] BITS SAY SO, MAKE SURE CAIA ;[610] NO DEVICE, DO DEFAULTING JRST DVOUT9 ;[610] EXPLICIT DEVICE--GO USE IT SKIPN T2,O.DEV ;[610] IS THERE A DEFAULT DEVICE? JRST DVOUT8 ;[610] NO, JUST GO USE DSK: MOVE T1,[3,,T2] ;[610] SEE IF THE DEFAULT DEVICE IS PATH. T1, ;[610] ERSATZ VIA A PATH UUO SETZ T3, ;[610] PROBABLY NOT TXNN T3,PT.IPP ;[610] IS IT ERSATZ? JRST DVOUT7 ;[610] NO, OK TO USE IT MOVE T2,F.MODM(P1) ;[610] DEFAULT DEVICE IS ERSATZ. WE CAN TXNN T2,FX.DIR ;[610] ONLY USE IT IF NO EXPLICIT PATH DVOUT7: SKIPN T2,O.DEV ;[610] OK TO USE THE DEFAULT DEVICE DVOUT8: MOVSI T2,'DSK' ;[610] CAN'T USE DEFAULT, JUST USE DSK: DVOUT9: MOVE T3,IO.CHN ;[610] RESTORE POINTER TO I.XXX BLOCK HRRZ T3,IO.PTR(T3) ;[610] (LOST TO DVOUT5) MOVEM T2,I.DEV(T3) ;[610] STORE FINAL DEVICE JRST DVCHK. ;[610] AND GO CHECK DATA MODE ;HERE TO DO ENTER FOR OUTPUT SPEC ;CALLED BY ; PUSHJ P,DVENT.## ;EXPECTS CHAN# IN IO.CHN ;ALSO DOES SWITCHES BEFORE FILE NAME DVENT.::PUSHJ P,DVCHK. ;GET DEVCHR, POINT TO I/O DATA BLOCK HLRZ T2,I.SWT(T1) ;ANY SWITCHES TO DO JUMPE T2,DVENTR ;BEFORE WE DO ENTER HRRZS I.SWT(T1) ;CLEAR SWITCHES DVENT1: MOVE T3,1(T2) ;GET UUO TLZ T3,(Z 17,) ;CLEAR CHAN# OR T3,I.CHN(T1) ;USE CORRECT ONE MOVE T1,T2 ;PRESERVE ADDRESS OF BLOCK TO DELETE MOVE T2,2(T1) ;GET REPEAT COUNT XCT T3 ;DO UUO SOJG T2,.-1 ;REPEAT? MOVEI T2,3 SKIPN 0(T1) ;MORE? JRST DVENT2 ;NO PUSH P,0(T1) ;YES PUSHJ P,DY.RET## PUSHJ P,DVCHN. ;RESET T1 POP P,T2 ;AND POINTER JRST DVENT1 ;AND LOOP ;HERE FOR LAST TIME DVENT2: PUSHJ P,DY.RET## PUSHJ P,DVCHN. ;GET DATA BLOCK DVENTR: SETZM I.ALC(T1) ;MAKE SURE ALLOCATION IS CLEAR MOVEI T2,I.RIB(T1) ;POINT TO LOOKUP/ENTER BLOCK HRLI T2,(ENTER) IOR T2,I.CHN(T1) ;BUILT INST MOVE T3,IO.CHR ;GET DEVCHR WORD TXNN T3,DV.DSK ;ONLY DSK CAN DO EXTENDED ENTERS ADDI T2,2 ;DO NORMAL 4 WORD ENTER PUSH P,I.PPN(T1) ;SAVE PATH FROM DESTRUCTION XCT T2 ;DO ENTER PUSHJ P,ENTERR ;FAILED POP P,I.PPN(T1) ;RESTORE PATH (MONITOR LIES) MOVE T1,IO.CHN ;GET CHAN# HRRZS IO.PTR(T1) ;SIGNAL DONE POPJ P, DEFINE XXX (CH,NUM,MODE)< IFN CH-%%,< REPEAT CH-%%,< 0 >> IFGE MODE,< IFIDN <.IODPR>,< NUM,0 > IFDIF <.IODPR>,< NUM,CH'BUF >> IFL MODE,< NUM,0 > %%==CH+1 > SYN XXX,XXXX %%==0 XALL OBFTBL: IODATA SALL PURGE %%,XXX,XXXX ;HERE TO DO SWITCH ACTION JUST PRIOR TO RELEASE ;AND TO DO RELEASE ;EXPECTS CHAN # IN IO.CHN DVRLS.::PUSHJ P,DVCLS. ;CLOSE FILE IF OPEN, GET DATA BLOCK JUMPE T1,CPOPJ ;GIVE UP IF NO ACTIVE I/O HRRZ T2,I.SWT(T1) ;ANY SWITCHES TO DO JUMPE T2,DVRLSZ ;NO, JUST RELEASE SETZM I.SWT(T1) ;CLEAR SWITCHES DVRLS1: MOVSI T3,(MTWAT.) ;INCASE TAPE STILL MOVING (DTA?) IOR T3,I.CHN(T1) XCT T3 MOVE T3,1(T2) ;GET UUO TLZ T3,(Z 17,) ;CLEAR CHAN# OR T3,I.CHN(T1) ;USE CORRECT ONE MOVE T1,T2 ;ADDRESS OF BLOCK TO DELETE MOVE T2,2(T1) ;REPEAT COUNT XCT T3 ;DO UUO SOJG T2,.-1 ;REPEAT IT? MOVEI T2,3 SKIPN 0(T1) ;MORE? JRST DVRLS2 ;NO PUSH P,0(T1) ;YES PUSHJ P,DY.RET## PUSHJ P,DVCHN. ;RESET T1 POP P,T2 ;AND POINTER JRST DVRLS1 ;AND LOOP DVRLS2: PUSHJ P,DY.RET## ;RETURN SWITCH BLOCK PUSHJ P,DVCHN. ;SETUP T1 AGAIN DVRLSZ: MOVSI T2,(RELEASE) IOR T2,I.CHN(T1) ;BUILD INST XCT T2 POPJ P, ;HERE TO DO CLOSE ;CALLED BY ; PUSHJ P,DVCLS. ;EXPECTS CHAN# IN IO.CHN DVCLS.:: IFN TOPS20,< MOVE T1,IO.CHN ;PICK UP CHANNEL SKIPN CHAN.JF(T1) ;[1511] JFN FOR THIS ONE? JRST DVCLS0 ;NO, DO UUOS MOVE T1,CHAN.JF(T1) ;[1511] CLOSF% ;DO IT JRST [ MOVE T1,IO.CHN;[1507] POPJ P, ] ;HMM, NOT SUCCESSFUL MOVE T1,IO.CHN ;ZERO OUT JFN SETZM CHAN.JF(T1) SETZM T1 ;ALSO T1 POPJ P, ;OK, RETURN DVCLS0: > ;[1401] IFN TOPS20 PUSHJ P,DVCHN. ;POINT TO I/O DATA BLOCK MOVSI T2,(CLOSE) IOR T2,I.CHN(T1) ;COMPLETE INST. XCT T2 POPJ P, ;HERE TO SET DEFAULT FILE NAME IF ZERO ;CALLED BY ; PUSHJ P,DVNAM. ;EXPECTS CHAN# IN IO.CHN DVNAM.::PUSHJ P,DVCHN. ;POINT TO I/O DATA BLOCK SKIPE T2,I.NAM(T1) ;GET USER SUPPLIED NAME POPJ P, ;YES, JUST RET SKIPE T2,LODNAM ;NOT SUPPLIED USE MAIN PROG NAME JRST .+3 ;HOWEVER IF STILL ZERO HLLZ T2,JOBNUM ;GET SIXBIT JOBNUMBER HRRI T2,'LNK' ;000LNK BY DEFAULT MOVEM T2,I.NAM(T1) POPJ P, ;HERE TO GET INTO UPDATE MODE FOR OVERFLOW FILES ;CALLED BY ; MOVEI T1,CHAN# ; PUSHJ P,DVUPD. ;RETURNS ;+1 FAILED (LOOKUP OR ENTER) ;+2 SUCCESS ;USES T1, T2, T3 DVUPD.:: IFN TOPS20,< CAIE T1,OC ;[1407] OVERLAY FILE? JRST DVUPDX ;[1407] NO, DO NATIVE UPDATE > ;[1407] ;IFE TOPS20,< HRLZ T2,T1 ;CHAN # IN LEFT LSH T2,5 ;THENCE TO AC FIELD MOVE T1,IO.PTR(T1) ;POINT TO DATA CHAN MOVEM T2,I.CHN(T1) ;STORE INCASE NEEDED HRRI T2,I.MOD(T1) ;ADDRESS OF OPEN BLOCK TLO T2,(OPEN) XCT T2 JRST E01OFD ;[1174] SHOULD NEVER HAPPEN FOR DSK HRRI T2,I.RIB(T1) ;POINT TO LOOKUP/ENTER BLOCK TLC T2,027000 ;OPEN .XOR. ENTER MOVE T3,I.PPN(T1) ;SAVE PPN INCASE DEFAULT PATH XCT T2 ;ENTER FILE POPJ P, ;FAILED MOVEM T3,I.PPN(T1) ;RESTORE DIRECTORY TLZ T2,007000 ;CONVERT TO CLOSE HRRI T2,CL.DLL ;BUT DON'T DEALLOCATE XCT T2 HRRI T2,I.RIB(T1) ;PUT LOOKUP ADDRESS BACK TLO T2,006000 ;LOOKUP XCT T2 POPJ P, ;FAILED MOVEM T3,I.PPN(T1) ;RESTORE DIRECTORY IFN TOPS20,< ;[1250] MOVX T3,RB.PRV+RB.MOD;[1250] SET UP FIELDS TO SAVE ANDM T3,.RBPRV(T2) ;[1250] CLEAR DATE/TIME FIELDS HLLZS .RBEXT(T2) ;[1250] SO PA1050 WON'T USE THEM MOVE T3,I.PPN(T1) ;[1250] GET BACK DIRECTORY > ;[1250] TLO T2,001000 ;ENTER XCT T2 POPJ P, ;FAILED JRST CPOPJ1 ;[1407] SUCCESS ;> ;[1401] IFE TOPS20 IFN TOPS20,< DVUPDX: MOVEM T1,IO.CHN ; CHAN# TO IO.CHN GLOBAL HRLZ T2,T1 ;[2301] CHAN # IN LEFT LSH T2,5 ;[2301] THENCE TO AC FIELD MOVE T1,IO.PTR(T1) ;[2301] POINT TO DATA CHAN MOVEM T2,I.CHN(T1) ;[2301] STORE INCASE NEEDED MOVEI T1,1(P) ;[1530] NOTE START OF FREE STACK ADJSP P,LN.FL ;[2017] GET SOME SPACE THERE PUSHJ P,DVTXT1 ;[1530] CREATE THE STRING MOVE T2,T1 ; AND NOTE BYTEPOINTER THERETO MOVX T1, ;[2247] CREATE NEW TEMP FILE MOVE T3,IO.CHN ;[2247] GET THE CHANNEL CAIE T3,DC ;[2247] .EXE FILE? JRST DVUPD1 ;[2247] NO PUSH P,T2 ;[2247] SAVE THE NAME POINTER GTJFN% ;[2247] NEED A SPARE JFN JRST [ ADJSP P,- ;[2301] REMOVE AC AND NAME BLOCK JRST DVERR. ] ;[2301] FAILURE MOVE T3,T1 ;[2247] GOT IT, HOLD ON TO IT POP P,T2 ;[2247] GET BACK THE FILESPEC MOVX T1, ;[2247] GET THE FLAGS BACK DVUPD1: GTJFN% ;[2247] GET THE JFN JRST [ ADJSP P,-LN.FL ;[2017] JRST DVERR. ] ;[2301] FAILURE ADJSP P,-LN.FL ;[2017] THROW AWAY STRING MOVE T2,IO.CHN ;[1461] PICK UP CHANNEL AGAIN MOVEM T1,CHAN.JF(T2) ;[1461] STASH JFN AWAY ... CAIN T2,DC ;[2247] IF .EXE FILE JRST CPOPJ1 ;[1461] DON'T BOTHER WITH AN OPENF MOVE T2,[BYTE (6)0(4).GSNRM] ; FILE BYTESIZE AND MODE IOR T2,[OF%RD!OF%WR!OF%THW!OF%DUD] OPENF% ; OPEN THE FILE JRST DVERR. ;[2301] FAILURE > ;[1401] IFN TOPS20 CPOPJ1: AOS (P) CPOPJ: POPJ P, ;HERE TO DELETE A FILE & RELEASE CHAN# ;CALLED BY ; MOVEI T1,CHAN# ; PUSHJ P,DVDEL. ;USES T1, T2 ;RETURNS ;+1 FAILED ;+2 SUCCESS DVDEL.:: IFN TOPS20,< PUSH P,T1 ;SET ASIDE CHANNEL # > ;[1401] IFN TOPS20 PUSHJ P,DVDLF. ;DELETE FILE IFE TOPS20,< POPJ P, ;NON-SKIP RETURNS (FAILURE)? > ;[1401] IFE TOPS20 IFN TOPS20,< JRST [ POP P,T1 POPJ P, ] ; RETURN POP P,T1 SKIPE CHAN.JF(T1) ;WAS HANDLED BY DELF? JRST [ SETZM CHAN.JF(T1) JRST CPOPJ1 ;YES, GOODBYE! ] > ;[1401] IFN TOPS20 TLC T2,024000 ;RELEASE_RENAME HLLZ T2,T2 ;CLEAR RHS INCASE CLOSE BITS EVER WORK XCT T2 JRST CPOPJ1 ;OK RETURN ;HERE TO JUST DELETE A FILE ;CALLED BY ; PUSHJ P,DVDLF. ;ARGS AS ABOVE DVDLF.:: IFN TOPS20,< SKIPN CHAN.JF(T1) ;[1513] IF A JFN EXISTS USE DELF JSYS JRST DVDLF0 ;OTHERWISE USE UUOS MOVE T1,CHAN.JF(T1) ;[1513] DELF% ;DELETE FILE SKIPA ;TOO BAD CLOSF% ;[1541] CLOSE IT SKIPA ;[1541] TOO BAD AOS 0(P) ;CLAIM SUCCESS JRST DVCEM. ;AND GO WIPE IO.ERG DVDLF0:> ;[1401] IFN TOPS20 HRLZ T2,T1 ;CHAN# IN LEFT LSH T2,5 ;THENCE TO AC FIELD MOVE T1,IO.PTR(T1) ;GET PTR TO DATA DVDLFC: ;ENTER HERE WITH T2 =CHAN # IN AC FIELD ;AND T1 POINTING TO DATA BLOCK ;NOW COPY FILE SPEC TO SAFE PLACE ;OTHERWISE STRANGE ERRORS OCCUR ON FUTURE RENAMES HRLZ T3,T1 ;FROM HRRZ T1,IO.EMG ;A SAFE PLACE HRR T3,T1 ;TO BLT T3,LN.IO-1(T1) ;T1 POINTS TO NEW BLOCK TLO T2,(CLOSE) ;CLOSE FILE INCASE STILL OPEN XCT T2 HRRI T2,I.RIB(T1) ;POINT TO LOOKUP BLOCK TLO T2,006000 ;CONVERT CLOSE TO LOOKUP PUSH P,I.PPN(T1) ;SAVE PATH OVER LOOKUP XCT T2 JRST DVDLF1 ;TOO BAD SETZM I.NAM(T1) ;CLEAR NAME TLC T2,023000 ;RENAME _ LOOKUP XCT T2 ;DELETE FILE JRST DVDLF1 ;TOO BAD AOS -1(P) ;OK RETURN DVDLF1: POP P,I.PPN(T1) ;RESTORE PATH FROM ENTRY ; PJRST DVCEM. ;CLEAR IO.EMG AND RETURN ;ROUTINE TO CLEAR IO.EMG, THE EMERGENCY FREE I/O DATA BLOCK ;CALLED BY ; PUSHJ P,DVCEM. ; ;USES T1,T3 ;*** WARNING *** MUST LEAVE T2 UNCHANGED DVCEM.::MOVE T1,IO.EMG ;GET POINTER TO I/O BLOCK HRLZ T3,T1 ;BLT TO CLEAR IO.EMG HRRI T3,1(T1) ;SO ITS FREE FOR NEXT TIME SETZM (T1) BLT T3,LN.IO-1(T1) POPJ P, ;HERE TO RENAME A FILE ;CALLED BY ; MOVE T1,IO.CHN+CHAN# OF NEW FILE ; MOVE IO.CHN CHAN# OF OLD FILE ; PUSHJ P,DVRNF. ;USES T1, T2, T3, T4 ;RETURNS ;+1 FAILED ;+2 SUCCESS DVRNF.::PUSH P,T1 ;SAVE T1 PUSHJ P,DVCLS. ;CLOSE OUT OLD FILE POP P,T2 ;RECOVER NEW NAME MOVEI T3,I.RIB(T1) ;ADDRESS TLO T3,(LOOKUP) IOR T3,I.CHN(T1) ;PLUS CHAN# PUSH P,I.PPN(T1) ;SAVE PPN IN CASE DEFAULT PATH XCT T3 ;LOOKUP JRST [POP P,0(P) ;ERROR - RESTORE STACK POPJ P,] ;AND GIVE ERROR RETURN TO CALLER POP P,I.PPN(T1) ;DON'T BELIEVE FALSE MONITOR VALUE TLC T3,023000 ;RENAME_LOOKUP HRRI T3,I.RIB(T2) ;POINT TO NEW NAME LDB T4,[POINT 9,I.PRV(T2),8] ;GET USER SPECIFIED PROTECTION SKIPE T4 ;UNLESS NOT SPECIFIED DPB T4,[POINT 9,I.PRV(T1),8] ;STORE IN OLD SO WE COPY IT MOVE T4,I.PRV(T1) ;GET DATE TIME ETC MOVEM T4,I.PRV(T2) ;SINCE SAME FILE HRRZ T4,I.EXT(T1) ;GET HIGH ORDER PART HRRM T4,I.EXT(T2) ; ALSO PUSH P,I.PPN(T2) ;SAVE PATH, SINCE MONITOR WIPES IT XCT T3 JRST DVRNFE ;TEST ERROR CONDITION POP P,I.PPN(T2) ;RESTORE TO BEFORE (MONITOR LIES) JRST CPOPJ1 ;OK RETURN DVRNFE: POP P,I.PPN(T2) ;RESTORE REAL PPN OF FILE HRRZ T4,I.EXT(T2) ;GET RENAME ERROR CODE CAIE T4,ERAEF% ;ALREADY EXISTS POPJ P, ;NO, JUST IGNORE THIS ERROR? PUSH P,I.NAM(T2) ;SAVE NAME PUSH P,T2 ;SAVE P2 EXCH T1,T2 ;GET POINTER TO 2ND FILE MOVE T2,I.CHN(T2) ;GET CHAN# TO 1ST FILE PUSHJ P,DVDLFC JRST [SUB P,[2,,2] ;BACKUP STACK POPJ P,] ;AND GIVE UP POP P,T1 ;RESTORE POINTER POP P,I.NAM(T1) ;AND NAME JRST DVRNF. ;TRY AGAIN ;DVUPD. TAKES THE CHANNELS FOR AN OUTPUT FILE (SAY, THE OVERLAY FILE) AND ITS ;ASSOCIATED OVERFLOW FILE, AND ATTEMPTS TO PUT THE OVERFLOW FILE EXACTLY WHERE ;THE OUTPUT FILE WILL EVENTUALLY GO. THE ASSUMPTION IS THAT THE FORMAT OF THE ;OVERFLOW FILE IS THE SAME AS THE EVENTUAL OUTPUT FILE, SO A SIMPLE RENAME MAY ;BE DONE AT THE END OF LOADING. ; ;THE METHOD USED IS TO TEMPORARILY OPEN AND ENTER THE OUTPUT FILE TO SEE WHERE ;IT WILL GO, AND THEN PUT THE OVERFLOW FILE IN THAT AREA. THIS HAS THE ADVANTAGE ;THAT ALL LOGICAL NAMES AND SEARCH LISTS ARE AUTOMATICALLY TRACKED DOWN FOR US ;BY THE MONITOR, AND FILES SUPERSEDING EXISTING ONES END UP ON THE CORRECT ;STRUCTURE. THE ARGUMENTS FROM THE EXTENDED ENTER AND PATH. UUOS WILL THEN TELL ;US WHERE THE OVERFLOW FILE SHOULD GO. ; ;THE DECISION TO DO A RENAME IN LNKXIT IS THEN MADE BY COMPARING THE DEVICE OF ;THE OVERFLOW FILE WITH THE DEVICE OF THE OUTPUT FILE. THIS REQUIRES THAT ALL ;LOGICAL NAMES, ERSATZ DEVICES, ETC. MUST BE RESOLVED INTO THE EXACT STRUCTURE ;AND PATH SO THAT THE OUTPUT FILE WILL END UP IN THE RIGHT PLACE. ; ;CALL: ; T1/ CHANNEL OF THE OUTPUT FILE ; T2/ CHANNEL OF THE ASSOCIATED OVERFLOW FILE ; ;RETURNS +1 IF THE OVERFLOW FILE COULD NOT BE OPEN, AND +2 IF IT COULD. THE ;OVERFLOW FILE WILL BE IN THE SAME AREA THAT THE OUTPUT FILE WILL GO, UNLESS ;THAT ISN'T A DISK. IN THAT CASE, THE OVERFLOW FILE WILL BE INITIALIZED ON ;DSK:[-]. ALSO, IF THE OVERFLOW FILE WAS PUT WHERE THE OUTPUT FILE WILL ;EVENTUALLY GO, THEN THE OUTPUT FILE'S SPEC WILL HAVE BEEN CHANGED FROM WHAT THE ;USER ACTUALLY TYPED (SAY, SYS:PROG.OVL) TO THE EXACT SPECIFICATION FOR THAT ;FILE (SAY, DSKB:PROG.OVL[1,5] IF /NEW WAS SET). DVSUP.::SPUSH ;[1230] SAVE SOME STABLE ACS MOVE P1,IO.PTR(T1) ;[1230] KEEP REAL CHANNELS AND POINTERS HRLI P1,(T1) ;[1230] TO I/O DATA BLOCKS AROUND MOVE P2,IO.PTR(T2) ;[1230] .. HRLI P2,(T2) ;[1230] .. HRROM P1,IO.PTR(T2) ;[1230] START WORK ON USER'S OUTPUT SPEC HLRZM P2,IO.CHN ;[1230] BY USING OVERFLOW FILE'S CHAN PUSHJ P,DVCHK. ;[1230] SEE IF USER'S FILE IS ON A DISK MOVE T1,IO.CHR ;[1230] .. TLC T1,-1-<(DV.TTA)> ;[1230] AND NOT ON NUL: TLCE T1,-1-<(DV.TTA)> ;[1230] .. TXNN T1,DV.DSK ;[1230] .. JRST DVSUP1 ;[1230] NOT A DISK--CAN'T OVERFLOW THERE ; .. ; .. PUSHJ P,DVOPN. ;[1230] OPEN ... PUSHJ P,DVENT. ;[1230] ... AND ENTER USER'S FILE MOVE T1,I.RIB+.RBDEV(P1) ;[1230] COPY THE EXACT DEVICE MOVEM T1,I.DEV(P1) ;[1230] FOR USE BY THE OUTPUT FILE MOVEM T1,I.DEV(P2) ;[1230] AND THE OVERFLOW FILE MOVE T1,IO.CHN ;[1230] COPY THE EXACT PATH ALSO MOVEM T1,I.PTH+.PTFCN(P1) ;[1230] BY DOING A PATH. UUO ON THE MOVSI T1,LN.SFD ;[1230] CHANNEL NOW OPEN AND ENTERED HRRI T1,I.PTH(P1) ;[1230] .. PATH. T1, ;[1230] .. SETZM I.PTH+.PTPPN(P1) ;[1230] NO PATH. UUO?! THEN [-] WORKS MOVSI T1,I.PTH(P1) ;[1230] COPY EXACT PATH FOR USE BY HRRI T1,I.PTH(P2) ;[1230] THE OVERFLOW FILE TOO BLT T1,I.PTH+LN.SFD-1(P2) ;[1230] .. MOVEI T1,I.PTH(P1) ;[1230] MAKE EACH ENTER BLOCK POINT MOVEM T1,I.RIB+.RBPPN(P1) ;[1230] TO ITS OWN PATH. BLOCK MOVEI T1,I.PTH(P2) ;[1230] .. MOVEM T1,I.RIB+.RBPPN(P2) ;[1230] .. HLLZS I.RIB+.RBEXT(P1) ;[1230] ZERO ANY ENTER ARGS THAT MAY MOVX T1, ;[1230] MAY HAUNT US LATER ANDM T1,I.RIB+.RBPRV(P1) ;[1230] .. SETZM I.RIB+.RBSIZ(P1) ;[1230] .. SETZM I.RIB+.RBSPL(P1) ;[1230] .. MOVSI T1,I.RIB+.RBALC(P1) ;[1230] .. HRRI T1,I.RIB+.RBALC+1(P1) ;[1230] .. SETZM T1,I.RIB+.RBALC(P1) ;[1230] .. BLT T1,I.RIB+LN.RIB-1(P1) ;[1230] .. MOVE T1,IO.CHN ;[1230] GET RID OF USER'S FILE NOW THAT RESDV. T1, ;[1230] WE KNOW WHERE IT WILL GO JFCL ;[1230] FORGET ERRORS JRST DVSUP2 ;[1230] NOW READY TO OPEN OVERFLOW FILE DVSUP1: MOVX T1,'DSK ' ;[1230] PUT OVERFLOW FILE IN DSK:[,] MOVEM T1,I.DEV(P2) ;[1230] .. SETZM I.RIB+.RBPPN(P2) ;[1230] .. ; JRST DVSUP2 ;[1230] NOW READY TO OPEN OVERFLOW FILE DVSUP2: HLRZ T1,P2 ;[1230] SET UP CHANNEL FOR OVERFLOW FILE HRRZM P2,IO.PTR(T1) ;[1230] UNDO USE OF OUTPUT FILE PUSHJ P,DVUPD. ;[1230] OPEN OVERFLOW FILE IN UPDATE MODE SKIPA ;[1230] FAILED--SKIP THE SKIP RETURN AOS -2(P) ;[1230] FILE OPENED SUCCESFULLY--SKIP SPOP ;[1230] RESTORE SAVED ACS POPJ P, ;[1230] DONE SUBTTL TOPS-20 JSYS ROUTINES IFN TOPS20,< ;HERE TO CONVERT SCAN BLOCK INTO TEXT STRING ;CALLED BY ; MOVEM AC,IO.CHN STORE CHANNEL # AWAY ; PUSHJ P,DVTXT. ;DVTXT1 ENTRY POINT IS FOR TIMES WHEN WE KNOW WHERE THE ; STRING OUGHT TO GO. DVTXT.::MOVEI T2,F.LEN ;GET SPACE TO STORE STRING PUSHJ P,DY.GET## DVTXT1::MOVE T4,T1 ;SAFER PLACE HRLI T4,(POINT 7) ;MAKE INTO BYTE PTR PUSH P,T4 ;[1402] SET ASIDE INITIAL PTR PUSHJ P,DVCHN. ;GET DATA BLOCK IN T1 SKIPN T3,I.DEV(T1) ;GET DEVICE JRST DVTXT2 ;NO DEVICE PUSHJ P,DVDPB. ;STORE MOVEI T2,":" IDPB T2,T4 DVTXT2: SKIPN T2,I.PPN(T1) ;[1407] SEE IF DIRECTORY JRST DVTXT3 ;NO ; THIS CODE DOESN'T DO ANYTHING USEFUL TODAY, BUT WHEN ; THE COMMAND SCANNER UNDERSTANDS DIRECTORY NAMES IT SHOULD ; BE PUT BACK INLINE. ; MOVEI T2,"<" ;OPEN IT ; IDPB T2,T4 ; PUSHJ P,DVDPB. ;STORE NAME ; MOVEI T2,">" ; IDPB T2,T4 ;CLOSE IT PUSH P,T1 ;[1407] SAVE AWAY DEV BLOCK PTR MOVE T1,-1(P) ;[1407] RE-USE STRING FOR DESTINATION MOVE T3,T1 ;[1407] CURRENTLY THE DEVICE PPNST% ERJMP DVTXT3-1 ;[1407] TOO BAD! EXCH T4,T1 ;[1407] NEW CURRENT BYTE POINTER POP P,T1 ;[1407] AND GET DEV BLOCK PTR BACK DVTXT3: MOVE T3,I.NAM(T1) ;[1402] PUSHJ P,DVDPB. SKIPN T3,I.EXT(T1) ;[1402] JRST DVTXT4 ;NO EXTENSION MOVEI T2,"." IDPB T2,T4 PUSHJ P,DVDPB. DVTXT4: SETZM T2 ;[1402] IDPB T2,T4 ;[1402] INSERT TRAILING NULL POP P,T1 ;[1402] GET BACK INITIAL TEXT PTR POPJ P, ;HERE TO STORE BYTE IN STRING ;CALLED BY ; T3 = SIXBIT WORD ; T4 = BYTE PTR ; PUSHJ P,DVDPB. ;USES T2 DVDPB.::JUMPE T3,CPOPJ ;[2101] EXIT IF DONE CONVERTING SETZ T2, LSHC T2,6 ;GET NEXT CHAR ADDI T2," " ;TO ASCII IDPB T2,T4 JRST DVDPB. ;[2101] LOOP UNTIL DONE ;DVGFO. - ROUTINE TO DO GTJFN FOR OUTPUT FILE ;EXPECTS TEXT STRING IN IO.PTR(IO.CHN) ;STORES JFN THERE ON COMPLETION DVGFO.::MOVE T4,IO.CHN ;GET CHAN# MOVSI 1,(1B0+1B17) ;OUTPUT SO VERSION# STUFF WORKS RIGHT HRRO 2,IO.PTR(T4) ;POINT TO TEXT STRING GTJFN% HALT EXCH T1,IO.PTR(T4) ;STORE JFN MOVEI T2,F.LEN PJRST DY.RET## ;REMOVE TEXT STRING >;[1401] END OF IFN TOPS20 SUBTTL ERROR MESSAGES E01OFD::PUSH P,IO.CHN ;[1174] PUT CHANNEL ON STACK .ERR. (I,0,V%L,L%F,S%F,OFD) ;[1174] E01NED::PUSH P,IO.CHN ;[1174] PUT CHANNEL ON STACK FOR LNKLOG .ERR. (I,0,V%L,L%F,S%E,NED) POPJ P, ;[1174] RETURNS IF CHAN WAS DC; TRY NOW ENTERR: MOVE T1,IO.CHN HRLI T1,(%ENT) ;[1123] SIGNAL ENTER MOVE T2,IO.CHR ;GET DEVCHR WORD TXNE T2,DV.DTA ;DTA MIGHT BE SPECIAL JRST [MOVE T2,IO.PTR(T1) ;[1174] GET DATA BLOCK POINTER HRRZ T3,I.EXT(T2) ;[1174] IF ERROR WAS ERPRT% CAXN T3,ERPRT% ;[1174] AS IT MEANS DIRECTORY FULL HLLOS I.EXT(T2) ;[1174] SIGNAL BY -1 JRST .+1] E01FEE::PUSH P,T1 ;[1174] SAVE CHANNEL FOR LNKLOG .ERR. (LRE,,V%L,S%D,L%D,FEE) ;[1174] POPJ P, E01FLE::PUSH P,IO.CHN ;[1174] REMEMBER WHAT # FAILED IFE TOPS20,< ;[2301] .ERR. (LRE,,V%L,S%D,L%D,FLE) ;[1174] > ;[2301] IFE TOPS20 IFN TOPS20,< E$$COF::.ERR. (LRE,.EC,V%L,S%D,L%D,COF,) ;[2301] .ETC. (NLN,.EC) ;[2301] CRLF .ETC. (STR,,,,,ERRJSY) ;[2301] Type error text >;[2301] IFN TOPS20 POPJ P, IFN TOPS20,< ;[2301] ;[2301] DVERR. - Routine to do store TOPS-20 error ;[2301] Stores error in right half of I.EXT(I) ;[2301] Expects channel in I.CHN DVERR.:: MOVEI T1,.FHSLF ;[2301] Get the fork handle GETER% ;[2301] Get the error in T2 DVERR1: PUSHJ P,DVCHN. ;[2301] Set pointer to I/O block HRRM T2,I.EXT(T1) ;[2301] Remember the error MOVE T1,IO.CHN ;[2301] Get the channel back SKIPN T1,CHAN.JF(T1) ;[2301] Get the JFN POPJ P, ;[2301] No JFN, just return TXO T1,CO%NRJ ;[2301] Don't return the JFN CLOSF% ;[2301] Close the file JFCL ;[2301] Probably not open POPJ P, ;[2301] Done >;[2301] IFN TOPS20 SUBTTL THE END FIOLIT: END