Trailing-Edge
-
PDP-10 Archives
-
bb-r775d-bm_tops20_ks_upd_4
-
sources/lnkfio.mac
There are 48 other files named lnkfio.mac in the archive. Click here to see a list.
TITLE LNKFIO - SUBROUTINES TO DO ALL FILE I/O FOR LINK
SUBTTL D.M.NIXON/DMN/JLd/JBC/JNG/PAH/DZN/PY/JBS 17-Dec-84
;COPYRIGHT (C) 1974, 1984 BY
;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
;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==2351 ;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.
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,<I/O data block not set up>) ;[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,<Illegal data mode for device >)
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,<HALT ;CAN NOT HAPPEN!!!>
IFN TOPS20,<MOVE T2,[2,,203] ;FAKE IT FOR 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 <MODE><.IODPR>,<
NUM,0
>
IFDIF <MODE><.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,<GJ%FOU!GJ%SHT> ;[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,-<LN.FL+1> ;[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,<GJ%FOU!GJ%SHT> ;[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 <P1,P2> ;[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,<INSVL. 777,RB.PRV> ;[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 <P2,P1> ;[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,<Cannot open file>) ;[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