1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-02 01:30:40 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

1167 lines
37 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE LNKFIO - SUBROUTINES TO DO ALL FILE I/O FOR LINK
SUBTTL D.M.NIXON/DMN/JLd/JBC/JNG/PAH/DZN/PY/JBS/HD/RJF 5-Feb-88
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1973,1986,1988.
; 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==2417 ;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.
;2403 New coporate Copywrote statement.
;2417 Update Copywrote statement to 1988.
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