1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-02 17:45:26 +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

1783 lines
56 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 DTASER - NEW FORMAT DECTAPE SERVICE FOR TD-10(PDP-10) - V635
SUBTTL T. WACHS/CHW/RCC/CMF/TW 15 DEC 87
SEARCH F,S
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1973,1988>
XP VDTASR,635 ;DEFINE GLOBAL VERSION NUMBER FOR LOADER MAP.
DTASER::ENTRY DTASER ;SO LOADER WILL GET DTASER WHEN IN /L MODE
SUBTTL DEFINITIONS
DIRBLK==^D100 ;NUMBER OF BLOCK FOR DIRECTORY
TOPBLK==1101 ;HIGHEST LEGAL BLOCK NUMBER
NAMSTR==^D83 ;1ST NAME WORD IN DIRECTORY
QUANT==3 ;NUMBER OF BLOCKS CAN READ BEFORE GIVING UP DTC
MINDIS==14 ;MINIMUM NUMBER OF BLOCKS TO SEARCH BEFORE
; DISCONNECTING FROM A TAPE
SPACE==4 ;NUMBER OF BLOCKS SEPARATING CONTIGUOUS BLOCKS
; OF A FILE
IFNDEF CPBIT,<CPBIT==-1>
;FLAGS IN RH OF IOS
UDSD==100
UDXX==200
;FLAGS IN LH OF IOS
IOSLEP==IOBEG
REDOIO==100
NOLINK==200
CHNGDR==400
RVERSE==1000
SINGL==2000 ;JUST READ OR WRITE 1 BLOCK
DMPMOD==4000
RWDIR==10000
DMPCLS==20000
NOBUF==40000 ;DATA GOING DIRECTLY INTO USER AREA
NOBUFC==737777 ;-NOBUF
REWBIT==100000
RUNBIT==200000
RECKON==400000 ;THIS TAPE IS DEAD-RECKONING.
; (MUST BE SIGN BIT)
SUBTTL INITIALIZATION
;SUBROUTINE TO INITIALIZE DTC
DTAINI: XMOVEI F,DTADDB## ;FIRST DDB
DTAINA: LDB T1,PDVTYP## ;DEVICE TYPE
CAIE T1,.TYDTA ;DECTAPE?
JRST DTAINB ;NO
XMOVEI T1,DTADIR##(F) ;ADDRESS OF DIRECTORY BLOCK
MOVEM T1,DLOC##(F) ;STORE
HLRZ F,DEVSER(F) ;LINK TO NEXT DDB
JUMPN F,DTAINA ;LOOP
DTAINB: MOVEI F,DTADDB## ;START AT FIRST CONTROL
DTAIN0:
IFN FTMP,<
LDB T1,DEYCPF## ;CONTROL ON THIS CPU?
CAME T1,.CPCPN##
JRST DTAIN1 ;NO
>; END IFN FTMP
XCT DTXINI##(F) ;CLEAR THE TD10
SETZM DSCON##(F) ;ZERO SOME FLAGS
SETZM LVFLAG##(F)
SETZM USEWRD##(F)
DTAIN1: ADDI F,DCONS## ;STEP TO NEXT CONTROL
CAIGE F,KONEND## ;AT END?
JRST DTAIN0 ;NO, CLEAR NEXT CONTROL
POPJ P, ;YES, EXIT
SUBTTL UUO LEVEL DISPATCH TABLE
JRST CPOPJ1## ;IT'S ONLINE
JRST DVPDTA ;DEVOP. UUO
JRST REGSIZ## ;SIZE CAN BE GOTTEN FROM DDB
JRST DTAINI ;INITIALISE DECTAPE CONTROL(S)
JSP T2,DTSCON ;HUNG TAPE
DTADSP::JSP T2,DTSCON ;UREL - RELEASE UUO
JSP T2,DTSCON ;UCLS - CLOSE UUO
OUTB: JSP T2,DTSCON ;UOUT - OUTPUT OR OUT UUOS
JSP T2,DTSCON ;UIN - INPUT OR IN UUOS
JSP T2,DTSCON ;ENTR - ENTER UUO
JSP T2,DTSCON ;LOOK - LOOKUP UUO
OUTD: JSP T2,DTSCON ;DMPO - OUTPUT UUO, DUMP MODE
JSP T2,DTSCON ;DMPI - INPUT M, DUMP MODE
JRST SETO ;SETO - SET OUTPUT BLOCK NUMBER
JRST SETI ;SET INPUT BLOCK NUMBER
JSP T2,DTSCON ;GETF - GET NEXT FREE BLOCK NUMBER
JSP T2,DTSCON ;RENAM- RENAME UUO
JRST ICLS ;CLOSE INPUT
JSP T2,DTSCON ;UTPCLR - CLEAR DIRECTORY
JSP T2,DTSCON ;MTAP - UUOTAPE M
HUNGTP
DISTAB: UREL
UCLS
UOUT
UIN
ENTR
LOOK
DMPO
DMPI
ONEONE: XWD 1,1
-177
GETF
RENAM
XWD -26,NAMSTR
Z UTPCLR
MTAP
DISDIS==DISTAB-DTADSP-1
SUBTTL GENERAL UUO LEVEL ROUTINES
DTSCON: PUSH P,W ;SAVE W FOR UUOCON
SKIPA W,[DTADDB##] ;ADDRESS OF 1ST CONTROL BLOCK
DTNCON: ADDI W,DCONS## ;POINT TO FIRST OR NEXT CONTROL BLOCK
MOVE T1,DTXDDB##(W) ;FETCH THE NAME OF ITS DECTAPES
XOR T1,DEVNAM(F) ;COMPARE IT WITH UNIT ASSOC WITH M
TLNE T1,-1 ;RIGHT FAMILY?
JRST DTNCON ;NO- CHECK NEXT CONTROL
XCT DTSCNI##(W) ;READ STATUS INTO T4
XCT DXCCNT##(W) ;READ FLAGS INTO T1
HRLI W,(T1) ;PUT INTO LH W
PUSHJ P,@DISDIS(T2) ;DISPATCH TO ROUTINE
SOS -1(P) ;STRAIGHT RETURN - COMPENSATE CPOPJ1
POP P,W ;RESTORE W FOR UUOCON
JRST CPOPJ1## ;RETURN TO UUOCON
MTAP: HRRZ T2,M ;MTAPE - GET OPERATION
CAIE T2,1 ;REWIND OR
CAIN T2,11 ;REWIND UNLOAD ARE LEGAL
SOJA T2,MTAP0
POPJ P, ;OTHERS ARE NO-OPS
;CLOSE INPUT DISPATCH
ICLS: TLNE F,LOOKB ;LOOKUP PERFORMED?
HRRZS IBLK##(F) ;CLEAR INDEX OF INPUT FILE
POPJ P,
SUBTTL LOOKUP
;LOOKUP A DIRECTORY ENTRY
LOOK: TRNE S,UDSD ;NON-STANDARD?
JRST CPOPJ1## ;YES. LOOKUP OK
PUSHJ P,DTRCHK ;MAKE SURE TAPE NOT REWINDING
PUSHJ P,DSERCH ;NO. FIND DIRECTORY ENTRY
AOJA M,CPOPJ## ;NOT THERE
HRRZ T2,26(T3) ;GET DATE, NO. OF 1K BLOCKS NEEDED
AOS M ;POINT UUO TO WORD 3
PUSHJ P,STORT2
HLRE T1,T3 ;GET INDEX
ADDI T1,27
SKIPN FSTBLK##(F) ;TAPE BEING WRITTEN?
HRLM T1,OBLK##(F) ;NO. SAVE INDEX FOR POSSIBLE OUTPUT
HRLM T1,IBLK##(F) ;SAVE INDEX FOR TEST OF
;ENTER OF SAME FILE.
PUSHJ P,BLKSRC ;COUNT NUMBER OF BLOCKS IN FILE
JRST BDDIR ;NO MENTION OF BLOCK IN DIRECTORY!
MOVEI T2,1 ;SET T2 TO COUNT BLOCKS
PUSHJ P,BLKSRB ;FIND NEXT MENTION IN DIRECTORY
AOSA M ;DONE. POINT TO E+3
AOJA T2,.-2 ;COUNT AND LOOK FOR NEXT
;T2 HAS THE NUMBER OF BLOCKS BELONGING TO THE FILE
IMUL T2,[-177] ;-NUMBER OF WORDS IF ALL BLOCKS FULL
JUMPL M,[MOVMS T2 ;GET +VE NUMBER OF WORDS IF EXTENDED UUO
JRST .+2] ;CONTINUE
HRLZS T2 ;SET TO STORE
PUSHJ P,STORT2 ;STORE IN DIRECTORY WD 4
SUBI M,2 ;POINT UUO TO DIRECTORY WD 2
TLZ S,IO ;MAKE SURE IO IS OFF
MOVEI J,DIRBLK ;NO. FIND FIRST MENTION OF BLOCK
PUSHJ P,LSTFRE+1 ;NEAR DIRECTORY
JUMPN J,LOOKE ;FOUND IF J NOT =0
PUSHJ P,BLKSRC ;FIND FIRST MENTION IN DIRECTORY
JRST BDDIR ;NOT THEERE - ERROR
LOOKE: PUSHJ P,GETDT ;GET DECTAPE CONTROL
MOVE T1,[-1,,BLKWRD##];GET IOWD TO READ 1ST WORD
ADDI T1,(W) ;RELOCATE FOR RIGHT CONTROL
MOVEM T1,DMPLST##(F) ;SAVE IT IN THE DDB
TLO S,SINGL ;JUST READ 1 RECORD
PUSHJ P,READBC ;GO READ THE BLOCK
;(CANT GO TO RDBLUK SINCE RWAIT MIGHT RETURN HERE)
PUSHJ P,RWAIT ;WAIT TILL IT'S IN
SETZM DMPLST##(F)
PUSHJ P,GETWDU## ;GET USER'S EXTENSION
HRR T1,IBLK##(F) ;GET FIRST BLOCK OF FILE
SKIPN FSTBLK##(F) ;IF FILE HAS NOT BEEN ENTERED
HRRZM T1,FSTBLK##(F) ;SAVE IN DDB
HLLM T1,DEVEXT(F) ;SAVE EXTENSION IN DDB FOR
; RENAME AND SUPERSEDING SHARED SEGMENTS
HLRZ T2,IBLK##(F)
ADD T2,DLOC##(F) ;POINT TO DIRECTORY
MOVEI T3,1 ;BIT FOR EXTENDED DATES
TDNE T3,-1(T2) ;EXTENDED BITS ON?
TRO T1,100000
TDNE T3,^D21(T2)
TRO T1,200000
TDNE T3,^D43(T2)
TRO T1,400000
PUSHJ P,PUTWDU## ;STORE EXTENSION AND BLOCK
; NUMBER IN USER'S AREA
JRST CPOPJ1## ;AND TAKE GOOD EXIT
;STORE T2 IN USERS AREA (PRESERVES T1 AND T2)
STORT2: EXCH T1,T2 ;PUT ARG IN T1 FOR PUTWDU
PUSHJ P,PUTWDU## ;STORE T1
EXCH T1,T2 ;RESTORE T1 AND T2
POPJ P, ;AND RETURN
SUBTTL RENAME
RENAM: TLO F,RENMB
PUSHJ P,DSER1 ;SEARCH FOR OLD NAME
AOJA M,RENER1 ;NOT FOUND - ERROR
SUBI M,1 ;FOUND. RESET M
PUSHJ P,GETWDU## ;GET FILE NAME
JUMPE T1,RENAM0 ;NOT EXTENDED IF 0
TLNE T1,-1 ;EXTENDED?
JRST RENAM0 ;NO
ADDI M,2 ;YES
PUSHJ P,GETWDU## ;GET NAME
RENAM0: EXCH T1,T3 ;RESTORE T1, NEW NAME IN T3
JUMPN T3,RENAM2 ;NOT RENAMING TO 0 IF IT GOES
SETZM (T1) ;YES. DELETE NAME IN DIR
SETZM 26(T1) ;DELETE EXTENSION
SETZM DEVFIL(F) ;ZERO DEVFIL
HLRE T1,T1 ;GET INDEX OF FILE
ADDI T1,27
PUSHJ P,DLETE ;DELETE ALL BLOCKS OF FILE
RENAM1: TLO S,CHNGDR ;DIRECTORY HAS CHANGED
TLO F,RENMB ;INDICATE RENAME
PUSHJ P,JDAADR##
HLLM F,(T1) ;SAVE THE BITS
AOS (P) ;SET FOR GOOD RETURN
SETZM IBLK##(F) ;IF ICLS NOT CALLED, NEXT ENTER SHOULD WIN
JRST STOIOS## ;GO TO USER
;COME HERE TO RENAME TO A REAL NEW NAME
RENAM2: MOVE U,T1 ;SAVE LOC OF NAME IN DIRECTORY
PUSH P,T3 ;SAVE NEW NAME
PUSHJ P,DSERCH ;SEARCH FOR NEW NAME
CAIA ;NEW NAME DOESN'T EXIST - OK
SOJA M,RENAM3 ;NEW NAME ALREADY EXISTS
POP P,(U)
PUSHJ P,GETWD1##
HLLM T1,26(U) ;SAVE IN DIR
HLLM T1,DEVEXT(F) ;SAVE INN DDB
JRST RENAM1 ;GIVE GOOD RETURN TO USER
RENAM3: POP P,T1 ;POP OFF NEW NAME
CAMN U,T3 ;DOES NEW NAME=OLD NAME?
JRST CPOPJ1## ;YES, JUST CHANGING "PROTECTION" - OK
JRST RENER2 ;NO, CAN'T RENAME TO AN EXISTING NAME
RENER1: TDZA T3,T3 ;RH E+1 =0
RENER2: MOVEI T3,4 ;RH E+1 =4
STOERR: PUSHJ P,GETWD1## ;GET SECOND WORD
HRR T1,T3 ;SET ERROR CODE
PJRST PUTWDU## ;STORE IT FOR THE USER
;SEARCH DIRECTORY FOR A MATCH
DSERCH: TLZ F,RENMB ;NOT RENAM-LOOKUP
DSER1: PUSHJ P,DIRCHK ;ENSURE DIRECTORY IS IN CORE
HRRZ T3,DLOC##(F) ;LOCATION OF DIRECTORY
ADD T3,[XWD -26,NAMSTR] ;POINT TO START OF NAMES
NMLOOK: TLNE F,RENMB ;RENAME
SKIPA T1,DEVFIL(F) ;YES, GET OLD NAME
NMLOO1: PUSHJ P,GETWDU## ;NO
JUMPE T1,CPOPJ## ;NULL ARGUMENT - ERROR RETURN
SKIPL M ;FIRST TIME THROUGH?
TLNE T1,-1 ;EXTENDED ARGUMENT LIST?
JRST NMLOO2 ;NO, CONTINUE
TLNE F,RENMB ;RENAME?
JRST NMLOO2 ;YES
ADDI M,2 ;POINT TO FILE NAME
TLO M,400000 ;INDICATE THAT WE HAVE BEEN HERE ONCE
JRST NMLOO1 ;GO GET FILE NAME FROM EXTENDED BLOCK
NMLOO2: MOVEM T1,DEVFIL(F) ;STORE FOR RENAME AND SUPERSEDING
; SHARED SEGMENTS
CAMN T1,(T3) ;TEST FOR MATCH
AOJA M,NMFOUN ;FOUND NAME. CHECK EXTENSION
AOBJN T3,.-2 ;TRY NEXT NAME
POPJ P, ;NOT FOUND
NMFOUN: TLNE F,RENMB ;RENAME?
SKIPA T1,DEVEXT(F) ;YES, GET NAME FROM DDB
PUSHJ P,GETWDU## ;NO, GET NAME FROM USER
XOR T1,26(T3) ;TEST AGAINST DIRECTORY EXTENSION
TLNN T1,-1 ;MATCH?
JRST CPOPJ1## ;YES. RETURN
AOBJP T3,.+2
SOJA M,NMLOOK ;NO. TRY NEXT NAME
SOJA M,CPOPJ## ;NAME NOT FOUND
;CHECK IF DIRECTORY IS IN CORE. IF NOT, READ IT
DIRCHK: TRNN S,UDSD ;DONT BOTHER IF NON-STANDARD
SKIPG DEVMOD(F) ;IS IT IN?
POPJ P, ;YES. RETURN
PUSHJ P,RTNEVM## ;GIVE UP EVM WHILE IO IS RIGHT IN S
TLZ S,IO+RVERSE ;NO, HAVE TO READ IT (FORWARD)
MOVEI J,DIRBLK ;BLOCK NUMBER
PUSHJ P,GETDT ;GET CONTROL
TLO S,RWDIR ;JUST READ 1 BLOCK
HRRZ T1,DLOC##(F) ;LOC OF DIRECTORY
HRLI T1,-200 ;READ 200 WORDS
MOVEM T1,DMPLST##(F) ;SAVE THE IOWD IN THE DDB
PUSHJ P,READBC ;GO READ IT
PUSHJ P,RWAIT ;WAIT TILL IN
MOVSI T2,DVDIRI ;SET DIRECTORY-IN-CORE BIT
ORM T2,DEVMOD(F)
POPJ P,
;SEARCH DIRECTORY FOR FILE WHOSE INDEX IS IN T1
BLKSRC: MOVSI U,(POINT 5) ;U IS A BLOCK POINTER
HRR U,DLOC##(F)
MOVEI J,1 ;START AT BLOCK 1
BLKSRA: ILDB T3,U ;INDEX OF NEXT BLOCK
CAMN T1,T3 ;MATCH?
JRST CPOPJ1## ;YES. RETURN
BLKSRB: CAIGE J,TOPBLK ;NO. SEARCHED LAST?
AOJA J,BLKSRA ;NO. TRY NEXT BLOCK
POPJ P, ;YES. RETURN
;SET UP POINTER TO DIRECTORY FOR BLOCK IN J
SETPTR: PUSH P,J ;SAVE J
PUSHJ P,DRPTR ;SET J AS A BYTE POINTER
MOVE U,J ;RETURN IT IN U
PJRST JPOPJ## ;RESTORE J AND RETURN
;GET NEXT AVAILABLE FREE BLOCK
;RESPECTS T1, T3
NXTFRE: PUSH P,T3 ;SAVE T3
PUSHJ P,SETPTR ;SET U TO A BYTE POINTER
MOVEI T1,0 ;LOOK FOR FREE BLOCKS
PUSHJ P,BLKSRA ;FIND A ZERO BLOCK
MOVEI J,0 ;NOT THERE- RETURN 0
JRST T3POPJ## ;RESTORE T3 AND RETURN
;GET PREVIOUS FREE BLOCK
LSTFRE: MOVEI T1,0 ;SET TO LOOK FOR FREE BLOCKS
PUSH P,T3 ;SAVE T3
ADDI J,2
PUSHJ P,SETPTR ;SET U AS A POINTER
SUBI J,2
LSTFR1: PUSHJ P,DECPTR ;DECREMENT BYTE POINTER
LDB T3,U ;INDEX TO BLOCK
CAME T3,T1 ;FOUND?
SOJG J,LSTFR1 ;TRY AGAIN IF NOT AT START
JRST T3POPJ## ;REACHED START - RETURN J=0
;DECREMENT BYTE POINTER
DECPTR: JUMPL U,DECPT1
ADD U,[BYTE (6) 5] ;DECREMENT
JUMPG U,CPOPJ## ;IF POSITIVE - SAME WORD
HRLI U,010500 ;RESET TO PREVIOS WORD
SOJA U,CPOPJ##
DECPT1: HRLI U,060500
SOJA U,CPOPJ##
;COME HERE TO DELETE THE FILE WHOSE INDEX IS IN T1
DLETE: MOVEI T2,0 ;SET TO DELETE BLOCKS
PUSHJ P,BLKSRC ;FIND A BLOCK BELONGING TO FILE
JRST CPOPJ## ;ALL THROUGH
DPB T2,U ;DELETE IT
SOS 1(P) ;ADJUST PDL FOR RETURN
AOBJN P,BLKSRB ;AND FIND NEXT MATCH
SUBTTL ENTER
;ENTER A FILE NAME IN DIRECTORY
ENTR: TRNE S,UDSD ;NON STANDARD?
JRST CPOPJ1## ;YES. RETURN
PUSHJ P,DTRCHK ;MAKE SURE NOT REWINDING
PUSHJ P,GETWDU## ;LOOK AT FIRST ARGUMENT
JUMPE T1,CPOPJ## ;ZERO IS AN ERROR
TLNE T1,-1 ;EXTENDED STY6 ENTER?
JRST ENTR1 ;NO
PUSH P,M ;SAVE M
ADDI M,2 ;POINT TO .RBNAM
PUSHJ P,GETWDU## ;GET THE FILE NAME
JUMPE T1,MPOPJ## ;ZERO IS ILLEGAL
POP P,M ;RESTORE M
ENTR1: PUSHJ P,DSERCH ;NO. LOOK FOR MATCH
JRST NEWENT ;THIS IS A NEW ENTRY
;HERE FOR A NON-NEW NAME ON THE ENTER
ENTR2: MOVE T1,T3
PUSHJ P,GETWT2
AOS M ;POINT TO WORD 3
HLLZ T3,T2 ;SAVE EXTENSION
LSH T2,-^D15
DPB T2,[POINT 3,T3,23]
PUSHJ P,GETWT2
ANDI T2,7777 ;LH(E+2) UNUSED
IOR T2,T3
TRNN T2,77777 ;IS DATE ALREADY THERE?
IOR T2,THSDAT## ;NO. ADD CURRENT DATE
HLRE T3,T1
ADDI T3,27
ADD T3,DLOC##(F)
MOVEI T4,1
ANDCAM T4,-1(T3)
TRZE T2,10000
IORM T4,-1(T3)
ANDCAM T4,^D21(T3)
TRZE T2,20000
IORM T4,^D21(T3)
ANDCAM T4,^D43(T3)
TRZE T2,40000
IORM T4,^D43(T3)
MOVEM T2,26(T1) ;INTO DIRECTORY
MOVE T4,OBLK##(F) ;IS THIS A SAVE FILE (UGETF DONE
;BEFORE THE ENTER?)
SUBI M,2 ;NO, POINT TO NAME
PUSHJ P,GETWT2
MOVEM T2,(T1) ;INTO DIRECTORY
HLRE T1,T1 ;COMPUTE INDEX OF FILE
ADDI T1,27
HLRZ U,IBLK##(F) ;INDEX OF INPUT FILE
SUB U,T1 ;WRITING SAME FILE AS READING?
JUMPE U,CPOPJ## ;TAKE ERROR RETURN IF YES
DPB T1,[POINT 17,OBLK##(F),17] ;SAVE INDEX IN DDB
PUSHJ P,DLETE ;DELETE ALL BLOCKS BELONGING TO FILE
AOJE T4,ENTRD ;FIND FIRST FREE BLOCK ON TAPE IF THIS
;IS A SAVE FILE (UGETF DONE)
MOVEI J,DIRBLK ;NO. GET 1ST BLOCK CLOSE TO
TLO S,RVERSE ;DIRECTORY, GOING IN REVERSE
PUSHJ P,USLSTA
CAILE J,TOPBLK ;BLOCK LEGAL?
JRST ENTRE ;NO. ERROR RETURN
ENTRC: MOVEM J,FSTBLK##(F) ;SAVE AS 1ST BLOCK
HRRM J,OBLK##(F) ;SAVE IN DDB
PUSHJ P,GETWD1## ;GET EXTENSION
HRR T1,FSTBLK##(F) ;SET 1ST BLOCK NUMBER
PUSHJ P,PUTWDU## ;SAVE IT IN THE USER'S AREA
MOVE J,FSTBLK##(F) ;RESTORE J
HLLM T1,DEVEXT(F) ;SAVE EXTENSION IN DDB ALSO
TLO S,NOLINK ;INDICATE THERE IS AN UNLINKED BLOCK
AOS (P) ;SET FOR SKIP RETURN
;AND FALL INTO MARKDR
;MARK DIRECTORY ENTRY POINTED TO BY J AS TAKEN
MARKDR: PUSHJ P,DRPTR ;SET POINTER TO BLOCK IN DIR
HLRZ T1,OBLK##(F) ;PICK UP INDEX
IDPB T1,J ;MARK DIRECTORY
TLO S,CHNGDR ;DIRECTORY HAS CHANGED
JRST STOIOS##
;;SET POINTER TO CORRECT DIRECTORY ENTRY
DRPTR: PUSH P,T1 ;SAVE T1 AND T2
PUSH P,T2
MOVEI T1,-1(J) ;SET FOR ILDB OR IDPB
IDIVI T1,7 ;COMPUTE WORD, POSITION
MOVEM T1,J ;DIRECTORY WORD NUMBER INTO J
MOVE U,T2 ;BYTE NUMBER INTO U
POP P,T2 ;RESTORE T1,T2
ADD J,DLOC##(F) ;GET CORRECT ADDRESS
HRLI J,(POINT 5) ;MAKE IT A BYTE POINTER
JUMPE U,TPOPJ## ;CORRECT FOR POSITION IN WORD
IBP J
SOJG U,.-1
JRST TPOPJ##
;HERE FOR NEW FILE NAME ON ENTER
NEWENT: SUB T3,[XWD 26,26] ;START AT BEGINNING OF DIRECT.
SKIPN (T3) ;FIND A FREE SLOT
AOJA M,ENTR2 ;RETURN WITH UUO POINTING TO WRD 2
AOBJN T3,.-2
MOVEI T3,2 ;ERROR CODE
JRST STOERR ;TELL USER NO FREE SLOTS
ENTRD: MOVEI T1,0 ;GET THE 1ST FREE BLOCK ON TAPE
PUSHJ P,BLKSRC ;AS THE 1ST LOGICAL BLOCK OF THE FILE
JRST ENTRE ;NONE AVAILABLE
JRST ENTRC ;CONTINUE WITH ENTER
;HERE WHEN NO FREE BLOCKS ON THE TAPE
ENTRE: LDB T1,[POINT 17,OBLK##(F),17] ;INDEX
ADD T1,DLOC##(F)
SETZM NAMSTR-1(T1) ;GET RID OF NAME
MOVEI T3,2
JRST STOERR ;GIVE ERROR RETURN TO USER
SUBTTL USETI/USETO/UGETF
;USETI - SET NEXT INPUT BLOCK TO READ
SETI: TDZ S,[XWD IOEND,IODEND] ;ZERO THE EOF BITS
SKIPA U,F ;STORE RH(M) IN THE DDB
;USETO - SET NEXT OUTPUT BLOCK TO WRITE
SETO: MOVEI U,1(F)
PUSHJ P,DWAIT ;WAIT FOR BUFFERS TO FILL (OR EMPTY)
HRRM M,IBLK##(U) ;SET BLOCK NUMBER
JRST STOIOS## ;STOE S, POPJ
;UGETF - GET NEXT FREE BLOCK FOR THIS FILE
GETF: PUSHJ P,DWAIT ;WAIT TILL BUFFERS EMPTY
PUSHJ P,DIRCHK ;ENSURE DIR. IN CORE
PUSHJ P,USRFRE ;GET NEXT AVAILABLE BLOCK
SKIPN OBLK##(F) ;HAS AN ENTER BEEN DONE?
SETOB J,OBLK##(F) ;NO, SET SWITCH SO THAT THE NEXT ENTER
;WILL FINF FIRST FREE BLOCK ON TAPE
MOVE T1,J ;TELL USER THE BLOCK NUMBER
JRST PUTWDU##
;GET NEXT (OR PREVIOUS) FREE BLOCK
USRFRE: MOVEI T3,SPACE ;BLOCKS "SPACE" APART
LDB J,PIOMOD## ;EXCEPT DUMP AND SAVE FILES
SKIPL OBLK##(F) ;UGETF DONE BEFORE ENTER?
CAIL J,SD ;OR ONE OF DUMP MODES?
MOVEI T3,2 ;YES, BLOCKING FACTOR=2
USRFRA: HRRE J,OBLK##(F) ;CURRENT BLOCK
TLNE S,RVERSE ;FORWARD?
JRST USRLST ;NO
ADDI J,(T3) ;YES. FIND NEXT BLOCK AT LEAST N
SKIPL J
CAILE J,TOPBLK
TDZA J,J
CALNXT: PUSHJ P,NXTFRE ;BLOCKS PAST THIS ONE
JUMPN J,STOIOS## ;RETURN IF FOUND
TLOE T3,1 ;FOUND NONE ON THIS PASS
JRST NOBLKS ;TAPE IS FULL
TLC S,RVERSE ;REVERSE DIRECTION
HRRI T3,1 ;START LOOKING AT NEXT BLOCK IN OTHER DIRECTION
JRST USRFRA
USRLST: SUBI J,(T3) ;LOOK FOR FREE BLOCK N BEFORE
SKIPG J
TDZA J,J ;REVERSE IF AT FRONT OF TAPE
USLSTA: PUSHJ P,LSTFRE ;THIS ONE
JRST CALNXT+1
;NO FREE BLOCKS AVAILABLE. GIVE HIGH BLOCK,SET IOBKTL LATER
NOBLKS: TLC S,RVERSE ;SET TO TRY BETWEEN CURRENT BLOCK
TLON T3,2 ; AND END OF TAPE IN ORIGINAL DIRECTION
JRST USRFRA ;TO IF HAVENT TESTED THAT ALREADY
MOVEI J,TOPBLK+1 ;SET HIGH BLOCK
POPJ P,
SUBTTL UTPCLR
;UTPCLR UUO
UTPCLR: TRNE S,UDSD
POPJ P, ;FORGET IT FOR NON-STANDARD
TLO S,SINGL+RWDIR ;INDICATE UTPCLR
PUSHJ P,DIRCHK ;MAKE SURE DIRECTORY IS IN CORE
TLZ S,SINGL+RWDIR ; DIRCHK MAY HAVE TO READ DIRECTORY
TLO S,CHNGDR ;DIRECTORY HAS CHANGED
HRRZ T1,DLOC##(F) ;LOC OF DIRECTORY
HRL T2,T1
HRRI T2,1(T1) ;BLT POINTER
SETZM (T1)
BLT T2,176(T1) ;LEAVE LAST WORD IN DIR. ALONE
MOVSI T2,17000 ;MARK DIRECTORY AS UNAVAILABLE
MOVEM T2,16(T1)
MOVSI T2,757000 ;RESERVE BLOCKS 1 AND 2
MOVEM T2,(T1) ;FOR READ IN MODE LOADER
MOVSI T2,777770 ;MARK BLOCKS 1102-1105 AS
ORCAM T2,NAMSTR-1(T1) ;UNAVAILABLE ALSO
TLO F,OUTPB ;SO RELEASE WILL WRITE DIRECTORY
PUSHJ P,JDAADR##
HLLM F,(T1)
JRST STOIOS##
;SUBROUTINE TO FETCH ITEM POINTED TO BY M INTO T2
;PRESERVES T1.
GETWT2: PUSH P,T1 ;SAVE T1
PUSHJ P,GETWDU## ;GET REQUESTED ITEM
MOVE T2,T1 ;ITEM TO T2
JRST TPOPJ## ;RESTORE T1 AND RETURN
SUBTTL CLOSE
;CLOSE UUO
UCLS: TLNN F,OUTPB ;IF NO OUTPUTS WERE DONE
JRST CLSDMP ; WRITE AN EMPTY BLOCK
TLNE S,NOLINK ;IS LAST BLOCK NOT LINKED?
TRNE S,UDSD ;AND NOT NON-STD?
JRST UCLS1 ;YES. RETURN
LDB T1,PIOMOD## ;NO. WRITE LAST BLOCK
CAIL T1,16 ;DUMP MODE?
JRST CLSDMP ;YES. CLOSE DUMP MODE
MOVE T1,DEVOAD(F) ;LOC OF BUFFER
EXCTUX <MOVE T2,1(T1)> ;LINK WORD
TLON T2,-1 ;LINK=-1 IF NOT SPECIFIED
EXCTXU <MOVEM T2,1(T1)> ;LINK = -1... EOF
MOVEM S,DEVIOS(F) ;SAVE S
PUSHJ P,OUT## ;GO TO WRITE RECORD
SKIPA ;IF TAPE DEAD-RECKONED
PUSHJ P,UCLS2
UCLS1: PUSHJ P,RWAIT ;DELAY, REDO IO IF DEAD-RECKONED
;HERE WHEN THE LAST BLOCK IS REALLY WRITTEN
SETZM OBLK##(F) ;MAKE SURE OBLK IS 0
SETZM FSTBLK##(F) ;SO NEW LOOKUP WILL SET LH(OBLK)
TLZ S,NOLINK ;CLEAR LINKED FLAG
TLZ F,OUTPB ;NO OUTPUTS DONE IF ANOTHER ENTER WITHOUT RELEASE
JRST STOIOS## ;AND LEAVE
;HERE TO CLOSE A DUMP MODE FILE
CLSDMP: TLO S,IO+DMPMOD ;SET SWITCHES
PUSHJ P,GETDT ;GET CONTROL
TLO S,DMPCLS ;SAFE TO SET BIT NOW
SETZM BUF##(W) ;ENSURE ZERO LINK,WORDCOUNT
SETZM BUF##+1(W) ;MAKE SURE 0, SO CAN GET WITH 3 SERIES MON.
;FILES SAVED WITH 4 SERIES MONITOR.
MOVEI T1,BUF##(W) ;POINT T1 AT BUFFER
PUSHJ P,OUFULL ;GO WRITE THE BLOCK
JRST UCLS1 ;AND LEAVE
;HERE TO REDO FINAL BLOCK
UCLS2: SKIPN DEVEVM(F)
PUSHJ P,GTOEVM## ;GET EVM AGAIN
TLNN S,DMPMOD
JRST OUTB
JRST OUTD
;ROUTINE TO ENSURE THAT A TAPE IS NOT REWINDING
DTRCHK: TLNN S,REWBIT ;REWINDING?
POPJ P, ;NO, RETURN
;YES, FALL INTO DWAIT
;ROUTINES TO WAIT FOR A (POSSIBLY) DEAD-RECKONING TAPE
DWAIT: PUSHJ P,WAIT1## ;WAIT TILL IOACT OFF
TLNE S,IOSLEP ;JOB SLEEPING?
SKIPL DEVIOS(F) ;TAPE DEAD-RECKONING?
POPJ P, ;NO, RETURN
PUSHJ P,SLPTST ;YES, SLEEP FOR A WHILE
JRST DWAIT ;AND GO TRY AGAIN
;THIS ROUTINE REENTERS CALLER IF TAPE WAS DEAD-RECKONING
;SINCE OTHERWISE NOTHING WILL DO THE I/O AFTER JOB SLEPT)
RWAIT: PUSH P,J ;SAVE J
MOVSI J,REDOIO ;MAKE SURE BIT IS OFF
ANDCAM J,DEVIOS(F)
PUSHJ P,WAIT1## ;WAIT
TDNN J,DEVIOS(F) ;DID TAPE DEAD-RECKON?
PJRST JPOPJ## ;NO, RETURN
PUSHJ P,SLPTST ;SLEEP FOR A WHILE
TLNN S,DMPCLS ;DONT GET CONTROL IF FROM CLOSE
PUSHJ P,GETDT1 ;GET CONTROL AGAIN
POP P,J ;RESTORE J
POP P,T1 ;RETURN TO CALLER AT INSTR BEFORE CALL
JRST -2(T1) ; SO THE I/O WILL ACTUALLY BE EXECUTED
;THIS ROUTINE GIVES UP EVM IF ANY BEFORE PUTTING A
; JOB TO SLEEP WHILE A TAPE DEAD RECKONS OR REWINDS
EWAIT:
IFN FTPSCD,<
AOS %DTASL## ;NUMBER OF DTA GENERATED SLEEPS
>
SKIPN DEVEVM(F) ;EVM?
PJRST SLEEPF## ;NO
PUSHJ P,RTEVM## ;RETURN EVM
PUSHJ P,SLEEPF## ;ZZZZZZ
PJRST RSTEVM## ;RESTORE EVM
SUBTTL RELEASE
;RELEASE UUO
UREL: MOVSI T1,DVDIRIN ;IF NONSTANDARD, WILL CLEAR
TRNE S,UDSD ;CLEAR NON-STANDARD BIT.
ANDCAM T1,DEVMOD(F) ;SO DIRECTORY WILL BE READ ANEW
MOVSI T1,IOSLEP ;IS TAPE DEAD-RECKONING?
SKIPGE DEVIOS(F)
IORM T1,DEVIOS(F) ;YES, MAKE SURE JOB SLEEPS
; (IOSLEP MIGHT HAVE BEEN CLEARED)
PUSHJ P,DWAIT ;MAKE SURE THE TAPE IS STOPPED
TLNN F,ENTRB+OUTPB+RENMB;IF NO ENTER/OUTPUT/RENAME ON THIS CHAN
JRST UREL3 ;ZERO IBLK AND RETURN IMMEDIATELY
PUSHJ P,NXTCM2 ;CLEAR OUT DUMP MODE STUFF
SKIPG DEVMOD(F) ;IF DIRECTORY HAS BEEN
TLZN S,CHNGDR ;MODIFIED IT MUSY BE WRITTEN
JRST UREL2 ;IT HASN'T BEEN CHANGED
TLZE S,NOLINK ;UNLINKED BLOCK?
PUSHJ P,CLSDMP ;YES. WRITE IT.
TLO S,IO
PUSHJ P,GETDT ;WAIT TILL DTC AVAILABLE
SKIPL DEVMOD(F) ;TAPE ASSIGNED SINCE JOB WENT INTO WAIT?
JRST UREL1 ;YES, DON'T WRITE DIRECTORY ON NEW TAPE
TLO S,RWDIR ;GOING TO WRITE DIRECTORY
MOVEI J,DIRBLK ;BLOCK NUMBER
HRRZ T1,DLOC##(F) ;LOC OF DIRECTORY
HRLI T1,-200 ;WRITE 200 WORDS
MOVEM T1,DMPLST##(F) ;SAVE IOWD IN DDB
PUSHJ P,WRTBLK ;WRITE THE DIRECTORY
PUSHJ P,RWAIT ;WAIT TILL IT HAS BEEN WRITTEN
JRST UREL2
UREL1: PUSHJ P,THRUTD ;GIVE UP CONTROL
UREL2: MOVE T1,DEVIAD(F) ;BITS 1,2 ARE COUNT OF CHANS
TLNE T1,200000 ;DEV INITED ON ANOTHER CHANNEL TOO?
QUANTL: POPJ P,QUANT ;YES. DONT ZAP S OR DDB
;SOME BITS IN THE S WORD AND THE DDB WILL NORMALLY BE CHANGED ON THE
;INTERRUPT LEVEL AFTER THE RELEASE, BUT HNGSTP CAN CAUSE THESE ACTIONS
;NEVER TO OCCUR, SO MAKE SURE THEY REALLY HAPPENED
TLZ S,77600 ;ZERO S BITS
TRZ S,UDSD
SETZM OBLK##(F) ;AND OBLK
SETZM FSTBLK##(F)
UREL3: SETZM IBLK##(F) ;ZERO IBLK SO WRITING A FILE AFTER READING
;IT WILL WORK (CHECK IS MADE AT ENTER)
SETZM SVDWRD##(F)
TLZ S,DMPMOD ;MAKE SURE BIT IS OFF
SETZM DEVFIL(F) ;CLEAR FILE AND EXTENSION
HRRZS DEVEXT(F) ;SO CONTROL-T DOES NOT PRINT THEM
JRST STOIOS## ;STORE S AND RETURN
SUBTTL GET DECTAPE CONTROL
GETDT0: MOVSI S,IOSLEP ;DWAIT WILL LOOP IF IOSLEP OFF
IORM S,DEVIOS(F)
PUSHJ P,DWAIT ;WAIT TILL TAPE STOPS REWINDING
;GET DEC TAPE CONTROLLER
GETDT: TLZE S,REWBIT ;IF TAPE IS REWIZDING NOW
JUMPL S,GETDT0 ;WAIT TILL THRU BEFORE CONTINUING
JUMPGE S,GETDT1 ;IF DEAD-RECKONING,
MOVEI T1,1 ;SLEEP FOR 1 SECOND
PUSH P,J
LDB J,PJOBN## ;JOB NUMBER
PUSHJ P,EWAIT ;ZZZZZZZZZ
POP P,J ;RESTORE J
MOVE S,DEVIOS(F) ;RESTORE S
JRST GETDT ;AND SEE IF SLEEPING NOW
GETDT1:
GETDT4: PUSHJ P,DXWAIT ;GET RESOURCE
PIOFF ;AVOID CLOCK INTERRUPT
SKIPE USEWRD##(W) ;SOMEONE ELSE ALREADY GRAB CONTROLL(AT CLOCK LEVEL)
JRST GETDT6 ;YES,GO WAIT SOME MORE
MOVEM F,USEWRD##(W) ;NO,SAVE AC NEEDED ON INTERRUPT LEVEL
PION
LDB T1,PUNIT## ;HAVE CONTROL NOW
LSH T1,11 ;CONNECT TO DTA
XCT DTXSTO##(W) ;SEE IF TAPE IS OK
XCT DTSCNI##(W) ;CONI DAS,T4
TLNE T4,10 ;IDLE? (SHOULD BE)
TRNE T4,100 ;SELECT ERROR?
JRST QUEST ;YES. COMPLAIN
TLNE S,IO ;NO. TRYING TO WRITE TAPE?
TRNN T4,4000 ;YES. WRITE PROTECTED?
SKIPA T1,QUANTL ;NO. EVERYTHING IS OK
JRST QUEST ;YES. COMPLAIN
HRRZM T1,QUANTM##(W) ;SET UP NUMBER OF BLOCKS TO KEEP CONTROL FOR
MOVEI T1,10000 ;SET UP TO DESELECT CONTROL
XCT DTXCON##(W) ; SO FNDBLK TEST WILL WORK (CONO DAC,20000)
JRST SETACT## ;LIGHT IOACT AND RETURN
;COME HERE TO COMPLAIN ABOUT UNIT NOT RIGHT (SELECT OR PROTECT ERROR)
QUEST: PUSH P,S ;SAVE S
PUSHJ P,THRUTD ;GIVE UP CONTROL
POP P,S
MOVEM S,DEVIOS(F)
PUSHJ P,HNGSTP## ;TYPE "DTAN OK?"
JRST GETDT1 ;GET CONTROL AGAIN AND RETRY
GETDT6: PION ;OK TO LET CLOCK INTERRUPT AGAIN
JRST GETDT4 ;WAIT TILL AVAL COMES UP
GETDTX: PUSHJ P,GETDT ;GET TD10
SKIPN DEVEVM(F) ;DID EVM GO AWAY (FROM REWINDING TAPE)?
PJRST RSTEVM## ;YES, GET IT AGAIN
POPJ P, ;NO, RETURN
SUBTTL INPUT
;DUMP MODE INPUT
DMPI:
IFN CPBIT, <
PUSHJ P,SAVE1## ;SAVE P1
HRRZ P1,IBLK##(F) ;SET P1=BLOCK TO READ
>; END IFN CPBIT
TLZ S,IO ;MAHE SURE IO IS OFF
PUSHJ P,DMPSET ;SET UP DUMP-MODE STUFF
TLOA S,DMPMOD
;INPUT UUO
UIN: TLZ S,DMPMOD
TLZ S,IO ;MAKE SURE IO=
PUSHJ P,SLPTST ;SLEEP IF DEAD-RECKONING
HRRZ J,IBLK##(F) ;BLOCK TO READ
PUSHJ P,STOIOS## ;SAVE S
TRNN S,UDSD ;NON-STANDARD?
JRST UIN1 ;NO, CONTINUE
TRNE S,UDXX ;YES, "SEMI-STANDARD"?
PUSHJ P,BLKCHK ;YES, CHECK BLOCK FOR LEGALITY
JRST UIN2 ;AN CONTINUE
UIN1: JUMPE J,EOF ;0 MEANS EOF
PUSHJ P,BLKCHK ;CHECK LEGALITY OF BLOCK NUMBER
TLNN S,DMPMOD ;DUMP MODE?
CAIE J,DIRBLK ;TRYING TO READ DIRECTORY?
JRST UIN2 ;NO. GO READ
;READING DIRECTORY - GIVE CORE IMAGE IF IT EXISTS
PUSHJ P,DIRCHK ;READ IT IF IT ISN'T1 IN ALREADY
SKIPN DEVEVM(F) ;GOT EVM? (MAY HAVE GIVEN IT UP IF DEAD RECKONING HAPPENED)
PUSHJ P,GTIEVM## ;NO, NEED IT TO MOVE DIRECTORY TO USER'S AREA
HRL T1,DLOC##(F) ;LOC OF DIRECTORY
MOVEI T2,@DEVIAD(F) ;WHERE USER WANTS IT
HRRI T1,1(T2) ;LOC OF DATA
BLT T1,200(T2) ;GIVE IT TO HIM
PUSHJ P,ADVBFF## ;ADVANCE BUFFERS
JFCL
PJRST RTNEVM
UIN2: TLNE S,DMPMOD ;DUMP MODE?
JRST READBC ;YES, GO START THE IO
PUSHJ P,GETDTX ;GET CONTROL (MIGHT BE MOVED BEFORE GETTING TD10
; SO CANT COMPUTE @DEVIAD TILL AFTER)
MOVEI T1,@DEVIAD(F) ;ADDRESS OF THE BUFFER
ADD T1,[-200,,1] ;MAKE AN IOWD
MOVEM T1,DMPLST##(F) ;SAVE IT IN THE DDB
JRST READBC ;AND START THE IO
;ROUTINE TO PUT JOB TO SLEEP IF TAPE IS DEAD-RECKONING AND IOSLEP IS ON
SLPTST: TLZN S,IOSLEP ;SHOULD JOB GO TO SLEEP?
POPJ P, ;NO, RETURN
MOVEM S,DEVIOS(F) ;YES, SAVE NEW S
JUMPGE S,CPOPJ## ;RETURN IF NOT DEAD-RECKONING
LDB J,PJOBN## ;JOB NUMBER
LDB T1,SLPNTR ;TIME TO SLEEP
PUSHJ P,EWAIT ;ZZZZZ
MOVE S,DEVIOS(F) ;RESTORE S
POPJ P, ;AND RETURN
;CHECK VALIDITY OF BLOCK NUMBER
BLKCHK: CAIG J,TOPBLK ;LEGAL?
JRST [HRLM J,DTXBLK##(F) ;SAVE AS LAST BLOCK FOR I/O
POPJ P,] ;RETURN
POP P,T1
TROA S,IOBKTL ;NO. LIGHT ERROR BIT
;INPUT BLOCK = 0 - END OF FILE
EOF: TLO S,IOEND ;LIGHT EOF BIT
TLNN S,DMPMOD
JRST STOIOS##
JRST DMPEOF ;GIVE UP CONTROL IF DUMP-MODE
SUBTTL OUTPUT
;DUMP MODE OUTPUT
DMPO: PUSHJ P,DIRCHK ;MAKE SURE DIRECTORY IS IN CORE
IFN CPBIT,<
PUSHJ P,SAVE1## ;SAVE P1
HRRZ P1,OBLK##(F) ;SET P1=BLOCK TO WRITE
>; END IFN CPBIT
TLO S,IO ;INDICATE OUTPUT
PUSHJ P,DMPSET ;SET DUMP-MODE POINTERS
TLOA S,DMPMOD
;OUTPUT UUO
UOUT: TLZ S,DMPMOD
TLNE S,REDOIO ;IF NOT DEAD-RECKONING,
TLNN S,NOLINK ;IF THE CURRENT BLOCK ISN'T LINKED,
JRST UOUT0
MOVEI T1,@DEVOAD(F) ;POINT TO BUFFER
SKIPL 1(T1)
HRRZS 1(T1) ;AND INDICATE NO LINK YET
;(ELSE WE'LL THINK A LINK EXISTS IF HAVE TO
; REWRITE AFTER DEAD-RECKONING)
UOUT0: TLO S,IO ;INDICATE OUTPUT
PUSHJ P,SLPTST ;SLEEP IF DEAD-RECKONING
MOVEM S,DEVIOS(F)
PUSHJ P,DIRCHK ;MAKE SURE DIRECTORY IS IN CORE
TLO S,IO ;IF DIRCHK READ, IO WENT OFF
HRRZ J,OBLK##(F) ;BLOCK TO WRITE
TRNN S,UDSD ;IF NON-STANDARD
JRST UOUT1
TRNE S,UDXX ;WANT BLOCK NUMBERS CHECKED?
PUSHJ P,BLKCHK ;YES, DO SO
JRST UOUT2 ;AND CONTINUE
UOUT1: CAIN J,DIRBLK ;CHECK IF WRITING DIRECTORY
JRST COR2HM ;YES. WRITE CORE IMAGE
JUMPE J,FAKADV ;DONT WRITE IF NO BLOCK GIVEN
PUSHJ P,BLKCHK ;CHECK FOR LEGAL BLOCK
UOUT2: TLNN S,DMPMOD ;ALREADY HAVE CONTROL IF DUMP-MODE
PUSHJ P,GETDTX ;GET DEC TAPE CONTROLLER
FILBUF: TLNE S,DMPMOD ;DUMP MODE?
JRST DMPFIL ;YES. FILL BUFFER FROM LIST
MOVEI T1,@DEVOAD(F) ;LOC OF BUFFER
ADD T1,[-200,,1] ;MAKE AN IOWD
MOVEM T1,DMPLST##(F) ;AND SAVE IT IN THE DDB
TLZ S,NOLINK ;INDICATE NOT LINKED
OUFULL: TRNE S,UDSD ;NON-STANDARD?
JRST OUTBL2 ;YES. NO FILE-STRUCTURED OPERATIONS
HLRE J,0(T1) ;IS IT LINKED?
JUMPL J,LSTBLK ;YES. - LAST BLOCK OF FILE
JUMPN J,OUTBLK ;IF NON-0 - YES
TLNE S,DMPCLS ;NO. LAST BLOCK OF A DUMP FILE?
;DMPCLS WILL BE TURNED OFF AT THE INTERRUPT
JRST OUTBLK ;YES. LINK MUST STAY 0
PUSH P,T1
PUSHJ P,USRFRE ;COMPUTE NEXT BLOCK
POP P,T1
TLOA S,NOLINK ;THIS BLOCK NOT LINKED
LSTBLK: MOVEI J,0
OUTBLK: HRLM J,0(T1) ;SAVE LINK IN 1ST WORD OF BLOCK
SKIPN J
TLO S,DMPCLS
MOVE T3,FSTBLK##(F) ;STORE 1ST BLOCK OF FILE IN WORD
DPB T3,[POINT 10,0(T1),27]
HRRZ J,OBLK##(F) ;BLOCK TO WRITE NOW
PUSHJ P,BLKCHK ;CHECK LEGALITY OF BLOCK
PUSHJ P,MARKDR ;MARK BLOCK TAKEN IN DIRECTORY
OUTBL2: HRRZ J,OBLK##(F)
PUSHJ P,STOIOS##
WRTBLK: PUSHJ P,FNDBLK ;GO SEARCH FOR BLOCK
MOVE T2,[BLKO DTC,700] ;HERE WE ARE - GO WRITE
JRST RDWRT
;TRYING TO WRITE DIRECTORY - STORE IN CORE
COR2HM: MOVEI T1,@DEVOAD(F) ;WHERE IT IS
HRLI T1,1(T1)
HRR T1,DLOC##(F) ;WHERE TO PUT IT
MOVEI T2,177(T1)
BLT T1,(T2)
TLO S,CHNGDR ;REMEMBER TO WRITE IT OUT
MOVSI T2,DVDIRI
ORM T2,DEVMOD(F) ;DIR. IS NOW IN CORE
SKIPA
FAKADV: TRO S,IOBKTL ;SOMETHING IS WRONG-LIGHT AN ERROR BIT
TLZE S,DMPMOD ;DUMP MODE?
JRST THRUTD ;YES. GIVE UP CONTROL
PUSHJ P,ADVBFE## ;ADVANCE BUFFERS
JFCL
TLZ S,NOLINK ;DIRECTORY BLOCK IS NOT LINKED
SETZM OBLK##(F)
JRST STOIOS##
;SET UP POINTERS AND STUFF FOR DUMP-MODE
DMPSET: PUSHJ P,SLPTST
PUSHJ P,GETDTX ;GET CONTROL
SETZM BADCOM##(F) ;REPEAT ERROR FLAG ON ENTRY
PUSHJ P,DMOHK ;GO CHECK FIRST COMMAND
SETOM LVFLAG##(W) ;MARK THIS AS UUO LEVEL SO COMMON
;CODE AT EXIT (IOGO2 AND FNDBL3) CAN
;DISTINGUISH
SKIPE BADCOM##(F) ;NON ZERO MEANS ERROR IN FIRST COMMAND
JRST SVADER ;SPECIAL ERROR EXIT ON SETUP
TLO S,DMPMOD ;LIGHT BIT
JUMPE T1,DMPTS1
IFN CPBIT, <
TRNE S,UDSD ;NO. NON-STD MODE?
JRST TOUSER ;YES. GO ELSEWHERE
>; END IFN CPBIT
MOVEM M,DMPLST##(F) ;NO, SAVE START OF LIST -1
SOS DMPLST##(F)
POPJ P,
DMOHK: PUSHJ P,DT3XCH ;SAVE ACS USED BY COMCHK
PUSHJ P,COMCHK## ;TO REPORT RESULTS & SET UP LIMITS
PUSHJ P,DT3XCH ;SAVE LIMITS AND RESULT-RESTORE ACS
POPJ P,
DT3XCH: EXCH T2,DJOTOP##(F) ;USER UPPER LIMIT RETURNS HERE
EXCH T3,DJOBOT##(F) ;USER LOWER LIMIT
EXCH S,BADCOM##(F) ;FLAG TO SHOW ADDRESS ERROR IF
POPJ P, ;NOT ZERO
;HERE TO START DUMP-MODE INTO USER AREA DIRECTLY
IFN CPBIT,<
TOUSER: JUMPE P1,NOBLK0 ;CANT READ BLK 0 IN NON-STD DUMP MODE
HLROM T1,BLKCNT##(W) ;SAVE INTTIAL WDCNT
MOVEM M,USPNTR##(W) ;SAVE ADR OF LIST
MOVEM M,SVPNTR##(W)
SOS SVPNTR##(W)
MOVEM T1,PNTR##(W) ;AND SAVE IT
SETOM DTXDMP##(W) ;INDICATE DUMP MODE
SETZM DMPLST##(F) ;MAKE SURE DMPLST = 0
TLO S,NOBUF ;INDICATE DIRECTLY TO USER
TLNN S,IO
POPJ P, ;READING - CONTINUE
POP P,T1 ;WRITING - THIS WILL SAVE LOTS OF TIME
JRST OUTBL2
NOBLK0: TRO S,IOIMPM
>; END IFN CPBIT
DMPTS1: POP P,T1
JRST THRUTD
;FILL OUTPUT BUFFER FROM LIST
DMPFIL: MOVSI T2,-177
ADDI T2,BUF##+1(W) ;RELOCATE INTO RIGHT CONTROL BLOCK
IFE CPBIT,<
TRNE S,UDSD
SUB T2,ONEONE ;200 DATA WORDS IF NON-STANDARD
>; END IFE CPBIT
DMPFLB: PUSHJ P,NXTCOM ;GET NEXT COMMAND
JRST DMPOTH ;END OF LIST
DMPFLA: MOVE T3,(T1) ;GET NEXT WORD
MOVEM T3,(T2) ;INTO BUFFER
AOBJP T2,DMPOVR ;BUFFER FULL IF GOES
AOBJN T1,.-3 ;GET NEXT WORD FROM COMMAND
JRST DMPFLB ;GET NEXT COMMAND
DMPOTH:
IFE CPBIT,<
TRNN S,UDSD
>; END IFE CPBIT
HRRZM T2,BUF##(W) ;LIST RAN OUT SAVE WORD COUNT
SETZM (T2) ;ZERO REST OF BUFFER
HRRZI T2,1(T2)
CAIL T2,BUF##+177(W) ;JUST ZERO 1 WORD IF AT TOP
JRST DMPOT1
HRLI T2,-1(T2)
BLT T2,BUF##+177(W)
DMPOT1: MOVNI T2,BUF##+1(W) ;CORRECT THE WORD COUNT
ADDM T2,BUF##(W)
JRST DMPOV1
;BUFFER FULL BEFORE END OF COMMAND
DMPOVR: AOBJN T1,.+3 ;WAS THAT LAST WORD OF COMMAND?
PUSHJ P,NXTCOM ;YES. GET NEXT
MOVEI T1,0 ;LAST
MOVEM T1,SVDWRD##(F) ;SAVE REMAINDER OF COMMAND
MOVEI T1,177
IFE CPBIT,<
TRNN S,UDSD
>; END IFE CPBIT
MOVEM T1,BUF##(W) ;WD CNT =177
DMPOV1: MOVEI T1,BUF##(W) ;SET T1 FOR 1ST WORD OF DATA
JRST OUFULL ;GO WRITE PART OF STUFF
;GET NEXT COMMAND FROM LIST
NXTCOM: SKIPN DMPLST##(F) ;END OF COMMANDS?
JRST NXTCM2 ;YES. RETURN
EXCH M,DMPLST##(F) ;POINT TO CURRENT IOWD
PUSHJ P,DT3XCH ;SAVE ACS AND GET BOUNDRIES
PUSHJ P,NXCMR## ;GET NEXT IOWD AND CHECK IT
PUSHJ P,DT3XCH ;SAVE RESULTS AND RESTORE ACS
EXCH M,DMPLST##(F) ;SAVE NEW POINTER
JUMPE T1,NXTCM2 ;END OF LIST
AOJA T1,CPOPJ1## ;GOOD RETURN WITH IOWD
;END OF DUMP-MODE LIST
NXTCM2: SETZM SVDWRD##(F) ;ZERO POINTERS
SETZM DMPLST##(F)
SETZM DTXDMP##(W)
POPJ P,
DMPFLC: SKIPN T1,SVDWRD##(F) ;IS THERE ANOTHER COMMAND
JRST DMPTH2 ;NO, THROUGH
JRST DMPFLA ;AND DO THE IOWD
DTC=320
DTS=324
;IO INTERFACE
RDBLUK: PUSHJ P,GETDT ;GET DT CONTROL
READBC: PUSHJ P,FNDBLK ;SEARCH FOR RIGHT BLOCK
MOVE T2,[BLKI DTC,300] ;FOUND IT - START READING
;HERE WITH J=BLOCK NUMBER, T2=FUNCTION. START SEARCH
RDWRT: OR T2,DXCNUM##(W) ;INSERT DEVICE NUMBER
HLLM T2,DXIOWD##(W) ;BLKI OR BLKO
TLNE S,DMPMOD
SKIPA T1,BFPNTR##(W)
MOVE T1,DMPLST##(F)
HRLI T2,(JFCL) ;ASSUME GOING FORWARD
TLNN W,100000 ;ARE WE?
SOJA T1,RDWRT1 ;YES
ADDI T1,176 ;NO, START AT TOP OF BLOCK
HRLI T2,(CAIA) ;SET TO SOS BLKI POINTER ON
; DATA-LEVEL INTERRUPT
RDWRT1: HLLM T2,DXDCTN##(W)
IFN CPBIT,<
TLNN S,NOBUF ;IF DIRECTLY TO USER
MOVEM T1,PNTR##(W) ; PNTR IS ALREADY SET UP
>; END IFN CPBIT
MOVEM S,DEVIOS(F)
PUSHJ P,DTXIOG##(W) ;WAKE UP THE CONTROLLER TO DO IO
DROUTH: SKIPN LVFLAG##(W) ;IS THIS FIRST TIME THROUGH
;THIS CODE FOR THIS UUO CALL
POPJ P, ;NO RETURN FROM INTERRUPT
SETZM LVFLAG##(W) ;YES. RESET FIRST TIME FLAG
DROUT1: PUSHJ P,DWAIT ;LET CALLING JOB WAIT UNTIL
;INTERRUPT LEVEL IO DONE
TLNN S,DMPMOD ;COMMAND FINISH?
JRST DROUT2 ;YES, RETURN
MOVE M,DMPLST##(F) ;LOC OF IOWD
SKIPN SVDWRD##(F) ;ADJUST M IS DMPLST IS TOO LOW
ADDI M,1 ;SINCE WE DIDN'T FINISH, MUST HAVE RECKONNED
; SO WE GAVE UP OUR EVM
PUSHJ P,RSTEVM## ;GET THE EVM BACK
HRRZ J,IBLK##(F) ;NO, GET NEXT BLOCK TO READ
PUSHJ P,RDBLUK ;START READING IT
JRST DROUT1 ;AND WAIT TILL DONE
DROUT2: SKIPE BADCOM##(F) ;WHERE THERE ANY LIST ERRORS?
JRST ADRERR## ;YES
POPJ P, ;NO
;HERE TO PERFORM A REWIND MTAPE FOR DTA
MTAP0: TLZ S,IO ;MAKE SURE IO IS OFF
PUSHJ P,GETDT ;GET THE CONTROL FOR THE TAPE
MOVEI T2,-1(M) ;RESET T2
LSH T2,15 ;T2=0 FOR REW; 10 FOR REW UNLD
TRZ S,IOACT ;CLEAR IOACT
TLO S,REWBIT+RVERSE(T2) ;SET SOME BITS IN S
MOVN J,T2 ;BLOCK = 0 OR -10
MOVSI T1,DVDIRIN
TLNE S,RUNBIT ;IF THIS IS AN UNLOAD
ANDCAM T1,DEVMOD(F) ; CLEAR DIRECTORY-IN-CORE
PUSHJ P,FNDBLK ;GO FIND BLOCK
;CONTROL COMES HERE ON THE INTERRUPT CHANNEL WHEN THE BLOCK IS FOUND
; IF THE TAPE DID NOT DEAD-RECKON, AND IS REWIND ONLY (NOT UNLOAD)
XCT DTSFNS##(W) ;FUNCTION STOP
POPJ P, ;DISMISS INTERRUPT
;COME HERE TO START READING BLOCK NUMBERS
FNDBLK: MOVEM J,BLOCK##(W) ;BLOCK WE'RE LOOKING FOR
POP P,DISPAD##(F) ;WHERE TO GO WHEN RIGHT BLOCK FOUND
SETZM ERRCNT##(W)
FNDBL2: SETZM TURNCT##(W)
XCT DXCCNT##(W) ;CONI DAC,T1
HRLI W,(T1) ;PUT CONI BITS IN LH(W)
LDB T1,PUNIT## ;GET UNIT NUMBER
LSH T1,11 ;POSITION IT
TLNE W,20000 ;TAPE SELECTED?
JRST FNDBL4 ;YES
TRO T1,230000 ;NO, SET TO SELECT TAPE FORWARD
TRNE S,UDSD ;NON-STANDARD?
TRNE S,UDXX ;YES, BUT START IN LAST DIRECTION IF UDXX IS ON
TLNE S,RVERSE ;LAST DIRECTION OF THE TAPE REVERSE?
TRC T1,300000 ;YES. SET FOR REVERSE
SKIPGE OBLK##(F) ;IS THE SPACING FACTOR 2?
TRC T1,300000 ;YES, START IN OPPOSITE DIRECTION
FNDBL3: TRO T1,DTBOTH##+200 ;ADD PI ASSIGNMENT
SETOM DTXSRC##(W) ;INDICATE SEARCHING FOR BLOCK NUMBERS
XCT DTXCON##(W) ;START SEARCH
XCT DTSENJ##(W) ;ENABLE FOR ALL BUT JOB DONE
TLNE S,DMPMOD ;DUMP MODE?
TLNN S,IO ;YES, OUTPUT?
SETZ T3, ;NO
TRNE S,UDSD
MOVEI T3,1
MOVEM T3,IOWRIT##(W) ;IOWRIT NON-0 IF DUMP-MODE OUTPUT
TLZ S,RECKON ;TURN OFF DEAD-RECKON BIT
PUSHJ P,STOIOS## ;SAVE S
IFN CPBIT,<
TLZ S,NOBUFC ;SET WORD NON-ZERO IF NOBUF ON
HLRZM S,DIRCTN##(W)
>; END IFN CPBIT
HRRZ T1,DMPLST##(F) ;ADR OF IOWD
CAIN T1,BLKWRD##(W) ;READING THE LINK ONLY?
SETOM DIRCTN##(W) ;YES, MUST BE GOING FORWARD
JRST DROUTH ;EXIT. CHECK FOR LIST ERRORS AFTER IO-DONE
FNDBL4: TLNE W,200000 ;DIRECTION TEST
TROA T1,200000 ;FORWARD
TRO T1,100000 ;REVERSE
JRST FNDBL3 ;START SEARCH
;INTERRUPT HERE TO READ A BLOCK NUMBER
SRCH:: XCT DTSCN2##(W) ;GET STATUS BITS
TLNE T1,2000 ;IS CONTROL STILL ACTIVE?
JRST SRCHD ;YES. MUST BE IN "PSEUDO END-ZONE"
XCT DTXDTI##(W) ;NO. READ A BLOCK NUMBER
ANDI T1,7777 ;REMOVE EXTRANEOUS BITS IN CASE P-8 DECTAPE
SKIPL BLOCK##(W) ;REWIND AND UNLOAD?
JRST SRCH1 ;NO
XCT DTXSF##(W) ;YES, TAPE ALREADY IN REVERSE?
JRST REKON1 ;YES, DISCONNECT IT
JRST SRCHTR ;NO, TURN IT AROUND
SRCH1: SUB T1,BLOCK##(W) ;CURRENT BLOCK - TARGET BLOCK
SKIPE DIRCTN##(W) ;MUST BE GOING FORWARD IF DUMP-MODE
JRST SRCHC ;DIRECTLY TO USER
JUMPE T1,FOUND ;=0 IF WE'RE THERE
XCT DTXSF##(W) ;IF TAPE IS IN REVERSE
MOVNS T1 ; SWITCH TURN-AROUND TEST
JUMPG T1,SRCHTR ;TURN AROUND IF POSITIVE
SRCH2: MOVMS T1
CAILE T1,MINDIS ;WORTH WHILE TO DISCONNECT TAPE?
JRST REKON ;YES. GO DISCONNECT
POPJ P, ;AND DISMISS THE INTERRUPT
;HERE TO TURN TAPE AROUND
SRCHTR: AOS T1,TURNCT##(W) ;NO OF TIMES TAPE WAS REVERSED
CAILE T1,3 ;TRIED ENOUGH?
JRST SRCHT1 ;YES, SET AN ERROR AND STOP TAPE
XCT DTXTRN##(W) ;NO, TURN THE TAPE AROUND
POPJ P, ;AND EXIT
SRCHT1: SETOM BLOCK(W) ;BLOCK=-1 IS AN ERROR FLAG
XCT DTSFNS##(W) ;GIVE A FUNCTION STOP
POPJ P, ;AND EXIT THE INTERRUPT
SRCHC: XCT DTXSF##(W) ;GOING FORWARD?
TLCA T1,400000 ;NO. SWITCH TURN AROUND TEST, ENSURE FORWARD
JUMPE T1,FOUND ;GO IF FOUND FORWARD
JUMPG T1,SRCHTR ;TURN THE TAPE AROUND IF NEGATIVE
SKIPL DIRCTN##(W) ;READING THE LINK ONLY?
POPJ P, ;NO, DISMISS THE INTERRUPT
XCT DTXSF##(W) ;YES, IN REVERSE?
TLC T1,400000 ;YES, SWITCH TURN-AROUND TEST
JRST SRCH2 ;DISCONNECT FROM TAPE IF A LONG DISTANCE
;COME HERE IF CONTROL IS STILL ACTIVE AFTER READING A BLOCK NUMBER
;THIS MEANS THAT TAPE IS IN THE "PSEUDO END-ZONE" - EXTRA FILLERS
;INSERTED FOR THE BENEFIT OF THE P-9
SRCHD: XCT DTXTRN##(W) ;TURN TAPE AROUND
POPJ P, ;AND EXIT THE INTERRUPT
;COME HERE WHEN A TAPE IS IN A LONG SEARCH
;IF THIS TAPE HAS NOT USED THE MONITOR BUFFER (READING), AND
;IF NO OTHER TAPES ARE DISCONNECTED, THIS ONE WILL BE,
;AND A CLOCK REQUEST WILL BE ENTERED FOR AN ESTIMATED TIME TO BLOCK.
REKON: SKIPN IOWRIT##(W) ;MONITOR BUFFER FULL?
SKIPGE DSCON##(W) ;STOPPING ALL DEAD-RECKONING DRIVES?
POPJ P, ;YES. FORGET IT
REKON1: MOVE T2,DISTNC##(W) ;OLD DISTANCE-TO-BLOCK
SKIPGE BLOCK##(W) ;REWIND AND UNLOAD?
JRST REKON2 ;YES
SUB T2,T1 ;NO, CHECK SEQUENCE
SOJN T2,TRYLTR ;JUMP IF NOT SEQUENTIAL BLOCKS
REKON2:
IFN FTMP,<
SKIPGE INTLBT##
SKIPL INTRLK## ;I KNOW IT'S UGLY
JRST TRYLTR ; BUT DEADLY EMBRACE IS WORSE
>; END IFN FTMP
MOVE F,USEWRD##(W) ;NO. DISCONNECT FROM THIS ONE
MOVE S,DEVIOS(F) ;SET UP S
MOVEI T2,^D19 ;COMPUTE NO OF SECONDS TO THE BLOCK
XCT DTXSF##(W) ; BASED ON 50 MS PER BLOCK FORWARD,
MOVEI T2,^D24 ; AND 40 MS PER BLOCK IN REVERSE
IDIVI T1,(T2) ;T1=NO OF SECS
TLNE S,RUNBIT ;REWIND AND UNLOAD?
ADDI T1,^D10 ;YES, ALLOW FOR TIME TO PULL TAPE OFF THE END
SKIPN T1 ;MAKE SURE TIME IS AT LEAST
MOVEI T1,1 ; 1 SECOND
DPB T1,SLPNTR ;SAVE TIME TO BLOCK IN DDB
TLO S,RECKON+IOSLEP+REDOIO ;INDICATE TAPE IS DEAD-RECKONING
;SET IOSLEP SO NEXT I/O WILL CAUSE JOB TO SLEEP
XCT DTXSF##(W) ;DETERMINE DIRECTION
TLOA S,RVERSE ;REVERSE
TLZ S,RVERSE ;FORWARD
XCT DTXDSL##(W) ;DESELECT THE CONTROL
;BIT 400000 IS TO PREVENT ERROR FLAGS FROM COMING IN LATER -
; IT DOES NOT CAUSE THE DESELECTED TAPE TO STOP THOUGH
SETZM USEWRD##(W) ;INDICATE NO TAPE IN USE
PUSHJ P,DXFREE ;FREE TD10
PUSHJ P,DEVERR## ;CAUSE UUOCON TO REENTER ROUTINE AT UUO LEVEL
; AT WHICH POINT JOB WILL BE PUT TO SLEEP
POPJ P, ;AND DISMISS INTERRUPT
TRYLTR: MOVEM T1,DISTNC##(W)
POPJ P, ;DISMISS INTERRUPT
SUBTTL ONCE/SECOND CODE
;ROUTINE CALLED ONCE A SECOND ON THE CLOCK
DTASEC::SKIPA W,[DTADDB##] ;START AT 1ST KONTROLLER
DTASE0: ADDI W,DCONS## ;NEXT CONTROL
CAIL W,KONEND## ;STILL IN CONTROL DATA BLOCKS?
POPJ P, ;NO, THROUGH
HRRZ F,W ;YES, SET F TO 1ST DDB IN CONTROL
IFN FTMP,<
PUSHJ P,CHKCPI## ;KONTROLLER ON THIS CPU?
JRST DTASE0 ;NO, LOOK AT NEXT ONE
>; END IFN FTMP
MOVSI T2,RECKON+REWBIT+RUNBIT;DEAD-RECKONING BIT
SKIPE T1,DSCON##(W) ;SOME TAPE TIME OUT WITH CNTROL IN USE?
AOS T1,DSCON##(W) ;YES
CAIGE T1,2 ;HAS IT BEEN 1 SECOND SINCE WE TRIED?
JRST DTASE3 ;NO
CONO PI,PI.OFF
XCT DTSCNI##(W) ;YES, HAVE TO STOP ALL TAPES
SETOM DSCON##(W) ;INDICATE SO
HLRZS T4 ;OLD PI ENABLES
ANDI T4,770000
XCT DTSCO2##(W) ;STOP ALL DISCONNECTED TAPES
CONO PI,PI.ON
MOVEI T3,0
DTASE1: SKIPL DEVIOS(F) ;IS THIS TAPE DEAD-RECKONING?
JRST DTASE2 ;NO
ANDCAM T2,DEVIOS(F) ;YES, NOW IT ISN'T
DPB T3,SLPNTR ;SLEEP-TIME =0
DTASE2: PUSHJ P,NXTDTA ;GET NEXT DTA DDB
JRST DTASE1 ;AND TEST THAT TAPE
SETZM DSCON(W) ;DONE - DSCON=0
JRST DTASE0 ;TRY NEXT CONTROLLER
;HERE ON A CLOCK INTERRUPT IF NOT TRYING TO STOP ALL TAPES
DTASE3: SKIPL DEVIOS(F) ;TAPE DEAD-RECKONING?
JRST DTASE5 ;NO
LDB T1,SLPNTR ;YES, GET SLEEP TIME
JUMPE T1,DTASE6 ;GO IF NOW 0
SUBI T1,1 ;DECREMENT THE TIME
DPB T1,SLPNTR
JUMPN T1,DTASE5 ;IF NOW 0,
DTAS3A: SKIPE USEWRD##(W) ;IS CONTROL FREE?
JRST DTASE4 ;NO
LDB T1,PUNIT## ;YES, GET UNIT
LSH T1,11 ;POSITION THE BYTE
PUSHJ P,REWFIN ;FINISH UP IF TAPE BEING UNLOADED
XCT DTXSTO##(W) ;STOP THE TAPE
ANDCAM T2,DEVIOS(F) ;NO LONGER DEAD-RECKONING
XCT DTXDST##(W) ;DESELECT CONTROL
JRST DTASE5 ;AND TRY NEXT DDB
;HERE IF A TAPE TIMES OUT AND THE CONTROL IS IN USE
DTASE4: SKIPN T1,DSCON##(W) ;ALREADY WAITING FOR THE CONTROL TO FREE UP?
MOVEI T1,1 ;NO, NOW WE ARE
MOVEM T1,DSCON##(W) ;STORE FLAG
DTASE5: PUSHJ P,NXTDTA ;GET NEXT DDB
JRST DTASE3 ;TEST IF IT'S DEAD-RECKONING
JRST DTASE0 ;DONE - TEST NEXT CONTROL
;HERE IF THE DEAD-RECKON TIME BYTE IS ALREADY 0
DTASE6: SKIPN DSCON##(W) ;IF NOT WAITING FOR CONTROL,
JRST DTAS3A ;STOP THE DRIVE
JRST DTASE5 ;AND TRY NEXT DDB
;SUBROUTINE TO FIND THE NEXT DTA DDB
;ENTER WITH F= CURRENT DDB
;RETURN CPOPJ WITH F= NEXT DTA DDB
;RETURN CPOPJ1 IF NEXT DDB IS NOT A DTA
NXTDTA: HLRZ F,DEVSER(F) ;NEXT DDB
MOVE T1,DEVMOD(F)
TLNN T1,DVDTA ;IS IT A DTA?
JRST CPOPJ1## ;NO, SKIP-RETURN
MOVE T1,DEVNAM(F) ;YES, IS IT RIGHT CONTROL?
XOR T1,DTXDDB##(W)
TLNE T1,-1
AOS (P) ;NO, SET FOR SKIP-RETURN
POPJ P, ;RETURN CPOPJ OR CPOPJ1
;ROUTINE TO STOP ALL TAPES WITH THE SLEEP-TIME =0
;CALLED WHEN CONTROL IS AVAILABLE (IF DSCON IS NON-0)
STOPIT: XCT DXCCNT##(W)
MOVE T4,T1 ;CONI BITS INTO T4
ANDI T4,7000 ;CURRENT UNIT
PUSH P,F ;SAVE F
HRRZ F,W ;START AT 1ST TAPE ON CONTROL
MOVSI T2,RECKON
STOPI1: SKIPL DEVIOS(F) ;IS TAPE DEAD-RECKONING?
JRST STOPI2 ;NO
LDB T1,SLPNTR ;YES, GET SLEEP-TIME
JUMPN T1,STOPI2 ;IF 0,
LDB T1,PUNIT## ;GET UNIT
LSH T1,11
PUSHJ P,REWFIN ;FINISH UP IF TAPE BEING UNLOADED
XCT DTXSTO##(W) ;STOP THE TAPE
ANDCAM T2,DEVIOS(F) ;TURN OFF DEAD-RECKON BIT
STOPI2: PUSHJ P,NXTDTA ;STEP TO NEXT DDB
JRST STOPI1 ;STOP IT IF TIME=0
SETZM DSCON##(W) ;DONE - ZERO DSCON
MOVEI T1,30000(T4) ;CONNECT CONTROL BACK TO OLD UNIT
XCT DTXCON##(W)
JRST FPOPJ## ;RESTORE F AND RETURN
;ROUTINE TO FINISH UP IF A TAPE WAS BEING UNLOADED
REWFIN: PUSH P,T2 ;SAVE T2
MOVE T2,DEVIOS(F) ;IOS
TLZN T2,RUNBIT ;TAPE BEING UNLOADED?
JRST REWFI1
XCT DTXTR2##(W) ;YES, TURN IT AROUND(SO BRAKES WILL WORK)
TLZ T2,RVERSE ;START FORWARD NEXT TIME
REWFI1: TLZ T2,REWBIT+IOSLEP ;ZERO REWBIT
MOVEM T2,DEVIOS(F) ;SAVE NEW S
JRST T2POPJ## ;RESTORE T2 AND RETURN
;HERE WHEN CORRECT BLOCK NUMBER IS FOUND
FOUND: MOVEM T3,FNDTMP##(W)
MOVE F,USEWRD##(W) ;SET UP F
MOVE S,DEVIOS(F) ; AND S
PUSHJ P,@DISPAD##(F) ;DISPATCH
MOVE T3,FNDTMP##(W) ;RESTORE T3
SETZM DTXSRC##(W) ;INDICATE NOT SEARCHING (DATA TRANSFER)
POPJ P, ;RESTORE ACS AND EXIT
;HERE WHEN DUMP-MODE POINTER RUNS OUT
IFN CPBIT,<
DMPADV::MOVE F,USEWRD##(W)
LDB J,PJOBN## ;JOB NUMBER
EXCH M,USPNTR##(W) ;POINTS TO CURRENT IOWD IN DUMP COMMAND LIST
PUSHJ P,DT3XCH ;SAVE ACS AND GET BOUNDRIES
PUSHJ P,NXCMR## ;GET NEXT IOWD AND CHECK IT
PUSHJ P,DT3XCH ;SAVE RESULT AND RESTORE ACS
EXCH M,USPNTR##(W) ;ALSO SAVE NEW POINTER AND RESTORE UUO
JUMPE T1,DMPAV3 ;ZERO COMMAND IS LIST END
;UPDATE WORD COUNT. THIS MUST BE DONE
HLRE T2,T1 ;HERE AS EACH WORD IS SEEN
ADDM T2,BLKCNT##(W) ;SUBTRACT NEGATIVE COUNT
MOVEM T1,PNTR##(W) ;NEW POINTER
POPJ P, ;AND EXIT THE INTERRUPT
DMPAV3: XCT DTSFNS##(W) ;GIVE FUNCTION STOP
SETZM DTXDMP##(W)
POPJ P, ;AND EXIT THE INTERRUPT
>; END IFN CPBIT
;INTERRUPT HERE FOR FLAG CHANNEL
DTXINT::TRNE T4,20000 ;END ZONE?
JRST TURN ;YES TURN TAPE AROUND
MOVE F,USEWRD##(W) ;RESTORE F
MOVEM T4,DEVSTS(F) ;STORE CONI BITS IN DDB
HRRM T4,DTXBLK##(F) ;SAVE HERE TOO
MOVE S,DEVIOS(F) ;AND S
LDB J,PJOBN## ;JOB NUMBER
SKIPGE BLOCK##(W) ;BAD BLOCK NUMBER?
TROA S,IODTER ;YES, LIGHT IODTER AND RETURN
TLZE S,REWBIT ;NO, FROM A REWIND MTAPE?
JRST REWDUN ;YES. DONE
TRNE T4,100000 ;JOB DONE?
TRNE T4,670000 ;AND NO ERRORS?
JRST ERRS ;NO. TOUGH LUCK
TLNN S,IO ;READING?
AOSA DTXWRD##(F) ;YES...KEEP COUNT OF BLOCKS READ
AOS DTXWWT##(F) ;NO...ADD TO COUNT OF BLOCKS WRITTEN
DTAIN2: TLNE S,DMPMOD ;DUMP MODE?
JRST DMPTHR ;YES. GO ELSEWHERE
TLNN S,RWDIR
TLNN S,SINGL
JRST .+3
LDB T1,[POINT 10,BLKWRD##(W),27] ;GET 1ST BLOCK NO. IF READ
;CAME FROM LOOKUP
HRRM T1,IBLK##(F) ;STORE IN DDB
;NO. IN IO WAIT?
PUSHJ P,SETIOD## ;YES. TAKE OUT OF WAIT
TLZE S,SINGL+RWDIR ;DIRECTORY OPERATION OR
;CLOSING DUMP FILE?
JRST THRUTP ;YES. LEAVE
TLNE S,IO ;WRITING?
JRST OUTHRU ;YES
;HERE ON END OF AN INPUT BLOCK
MOVE T3,DMPLST##(F)
HRROI T2,177 ;MASK OUT 1ST-BLK DATA
TRNN S,UDSD ;UNLESS IN NON-STD
ANDM T2,(T3)
HLRZ J,(T3) ;NEXT BLOCK TO READ
TRNE S,UDSD ;IF NON-STD
AOSA J,IBLK##(F) ;READ SEQUENTIAL BLOCKS
HRRM J,IBLK##(F) ;SAVE IN DDB
TRNE S,IODTER+IODERR+IOIMPM
JRST THRUIN
PUSHJ P,ADVBFF## ;GET NEXT BUFFER
JRST THRUIN ;EMPTY BUF NOT AVAILABLE
SKIPLE DSCON##(W) ;TAPE TIMED OUT?
PUSHJ P,STOPIT ;YES, STOP IT NOW
JUMPE J,THRUIN ;EXIT IF EOF OR BLOCK TOO LARGE
CAILE J,TOPBLK ;THE ERROR WILL BE CAUGHT ON THE
JRST THRUIN ;UUO LEVEL NEXT TIME AROUND
MOVEI T1,@DEVIAD(F) ;ADRESS OF THE USER'S BUFFER
ADDI T1,1 ;POINT TO LINK WORD
HRRM T1,DMPLST##(F) ;SAVE LOC IN DDB
SOSGE QUANTM##(W) ;HAS TAPE HAD CHAN LONG ENOUGH?
SKIPG @DTXREQ##(W) ;YES. ANYONE ELSE WANT IT?
JRST READBC ;NO. READ NEXT BLOCK
THRUIN: HRRZ T1,OBLK##(F) ;TAPE ALSO BEING WRITTEN?
JUMPN T1,THRUTP ;YES. DONT CHANGE REVERSE BIT
TLZ S,RVERSE ;NO. SET S BIT TO CORRECT DIRECTION
TLNE W,100000
TLO S,RVERSE ;SKIP OVER THRUTH INTO THRUTP
;HERE WHEN TAPE IS DONE
THRUTP: SETZM DMPLST##(F)
MOVEM S,DEVIOS(F) ;SAVE S IN DDB
XCT DTXSTP##(W) ;STOP TAPE
SKIPLE DSCON##(W) ;HAS A TAPE TIMED OUT?
PUSHJ P,STOPIT ;YES, STOP IT NOW
THRUTD: PUSHJ P,DXFREE ;FREE TD10
MOVEI T1,10000 ;DESELECT CONTROL
XCT DTXCON##(W)
TLZ S,DMPMOD+NOBUF+REWBIT+RUNBIT+RWDIR+SINGL+DMPCLS
SETZM USEWRD##(W) ;INDICATE CONTROL NOW FREE
JRST CLRACT## ;RESET IOACT AND RETURN
;COME HERE IF A TAPE IS HUNG
HUNGTP: TLNN S,REWBIT ;IGNORE IF REWINDING
JUMPGE S,HUNGT1 ;GIVE UP CONTROL IF NOT DEAD-RECKONING
JRST CPOPJ1## ;IGNORE IT IF DEAD RECKONING -
;WHEN THE TAPE TIMES OUT FNDBLK WILL RESET THE HUNG TIME, AND
;IF IT IS STILL HUNG AT ITS END THE ERROR MESSAGE WILL OCCUR
HUNGT1: TLNN S,IOW ;IS IOW SET?
PJRST THRUTP ;NO, DON'T TRY TO PRESERVE IT
PUSHJ P,THRUTP ;YES, CLEAR IOACT PARAMS
MOVSI S,IOW ;GET BIT TO RESTORE
IORB S,DEVIOS(F) ;SET IN S AND MEMORY
POPJ P, ;RETURN (GIVING HUNG DEVICE)
;HERE ON END OF OUTPUT BLOCK
OUTHRU: MOVE T1,DMPLST##(F) ;IOWD
HLRZ J,0(T1) ;GET LINK
TRNE S,UDSD ;NOW STD?
AOSA J,OBLK##(F) ;YES WRITE NEXT BLOCK NEXT
HRRM J,OBLK##(F) ;SAVE IN DDB AS NEXT BLOCK
PUSHJ P,ADVBFE## ;GET NEXT BUFFER
JRST THRUTP ;NOT FULL
SKIPLE DSCON##(W) ;HAS A TAPE TIMED OUT?
PUSHJ P,STOPIT ;YES, STOP IT NOW
HRRZ J,OBLK##(F) ;NEXT BLOCK TO WRITE
CAILE J,TOPBLK ;LEGAL?
JRST THRUTP ;NO. CATCH ERROR ON UUO LEVEL
SOSGE QUANTM##(W) ;YES. HAD CHAN LONG ENOUGH?
SKIPG @DTXREQ##(W) ;AND SOMEONE ELSE WANT IT?
JUMPN J,FILBUF ;NO. GO WRITE NEXT BLOCK IF NOT DONE
JRST THRUTP ;YES. GIVE UP TAPE
;TURN TAPE AROUND AFTER END-ZONE INTERRUPT
TURN: TLNE W,500 ;READING BLOCK NUMBERS?
JRST DIREOF ;NO. END ZONE WHILE READING DATA
XCT DTXTRN##(W) ;YES. TURN AROUND
AOS TURNCT##(W) ;INCREMENT NO OF TIMES TAPE HAS TURNED
POPJ P, ;RETURN ANND DISMISS THE INTERRUPT
;COME HERE ON AN END ZONE INTERRUPT WHILE READING DATA
;THIS CAN ONLY HAPPEN IN MODE 116,117
;LIGHT IODEND (IT IS A PREMATURE EOF) AND LEAVE
DIREOF: MOVE F,USEWRD##(W) ;RESTORE F
MOVE S,DEVIOS(F) ;AND S
JRST DMPEOF ;LIGHT IODEND AND RETURN
;COME HERE ON END OF DUMP MODE BLOCK
SVDMTH: SKIPLE DSCON##(W) ;HAS A TAPE TIMED OUT
PUSHJ P,STOPIT ;YES, STOP IT
IFN CPBIT,<
TLNE S,NOBUF ;DIRECTLY TO USER?
JRST USDMTH ;YES. ALMOST THROUGH
>; END IFN CPBIT
MOVSI T2,-177 ;SET UP COUNT
ADDI T2,BUF##+1(W) ;RELOCATE
CAIE J,DIRBLK ;IF DIRECTORY
TRNE S,UDSD ;OR NON-STANDARD
SUB T2,ONEONE ;GIVE WHOLE BUFFER
TLNN S,IO
JRST SVDMIN ;INPUT FILE
HLRZ J,BUF##(W) ;OUTPUT FILE. NEXT BLOCK
HRRM J,OBLK##(F)
JUMPE J,DMPTHA ;LAST BLOCK
IFE CPBIT,<
TRNE S,UDSD ;IF NON-STD MODE
AOSA OBLK##(F) ;WRITE CONSECUTIVE BLOCKS
>; END IFE CPBIT
CAIG J,TOPBLK ;NOT LAST. LEGAL BLOCK NUMBER?
POPJ P, ;YES. RETURN
TRO S,IOBKTL ;BLOCK TOO LARGE
DMPTHA: POP P,T1 ;REMOVE THE RETURN ADDRESS FROM
;CALL TO SVDMTH, SINCE
;NO MORE I/O WILL BE DONE
DMPTH2: PUSHJ P,NXTCM2 ;ZERO DUMP MODE STUFF
PUSHJ P,SETIOD## ;RESTART JOB
JRST THRUTP
;HERE ON END OF SAVE MODE INPUT BLOCK
SVDMIN: CAIN J,DIRBLK ;DIRECTORY
TDZA J,J ;YES LINK=0
HLRZ J,BUF##(W) ;NEXT BLOCK NUMBER
IFE CPBIT,<
TRNE S,UDSD ;NON-STANDARD?
AOSA J,IBLK##(F) ;YES. READ CONSECUTIVE BLOCKS
>; END IFE CPBIT
HRRM J,IBLK##(F) ;SAVE IN DDB
JRST CPOPJ1##
;HERE WHEN THROUGH DUMP-MODE DIRECTLY TO USER
IFN CPBIT,<
USDMTH: MOVEI T2,IBLK##(F)
TLNE S,IO
MOVEI T2,OBLK##(F) ;SET T2 TO RIGHT BLOCK NUMBER
MOVN T1,BLKCNT##(W) ;UPDATE BLOCK COUNTER
ADDI T1,177 ;ALLOW FOR PARTIAL BLOCKS
ASH T1,-7 ;DIVIDE WORD COUNT BY WORDS/BLOCK
ADDM T1,(T2)
JRST DMPTHA ;THROUGH
>; END IFN CPBIT
;HERE WHEN THROUGH DUMP MODE BLOCK
DMPTHR: PUSHJ P,SVDMTH ;END OF BLOCK HOUSEKEEPING
; RETURN ONLY IF MORE I/O
; WILL BE DONE
JRST DMPFLC ;FILL BUFFER FOR NEXT OUTPUT
;HERE WHEN THROUGH READING A DUMP-MODE BLOCK
SKIPN T1,SVDWRD##(F) ;PARTIAL COMMAND?
JRST DMIFLA ;NO, GET NEXT COMMAND
SOS DMPLST##(F) ;YES, RELOCATE IT
PUSH P,T2 ;SAVE POINTER TO DATA
PUSHJ P,NXTCOM
JRST DMPTHA ;HE WIPED OUT HIS IOWD GIVE ADR CHK
HLRE T2,T1 ;ORIGINAL WRDCNT
HLRE T3,SVDWRD##(F) ;CURRENT WRDCNT
SUB T3,T2 ;NO OF WRDS XFERRED
HRLS T3 ;SET TO UPDATE IOWD (JOB MAY NOT BE IN SAME PLACE)
ADD T1,T3 ;T1=IOWD REFLECTING (NEW) POSITION
POP P,T2
JRST DMIFLC ;AND CONTINUE
DMIFLA: PUSHJ P,NXTCOM ;NO. GET NEXT COMMAND
JRST DMPTH2 ;END OF LIST - THROUGH
DMIFLC: MOVE T3,(T2) ;NEXT DATA WORD
MOVEM T3,(T1) ;GIVE TO USER
AOBJP T2,.+3 ;IF BUFFER IS FULL
AOBJN T1,DMIFLC ;GET NEXT WORD
JRST DMIFLA ;GET NEXT COMMAND
AOBJN T1,.+3 ;BUFFER IS FULL. IS COUNT EXACTLY 177?
PUSHJ P,NXTCOM ;THAT COM. IS DONE. GET NEXT
JRST DMPTH2 ;END OF LIST - THROUGH
MOVEM T1,SVDWRD##(F) ;SAVE PARTIAL COMMAND FOR NEXT TIME
JUMPE J,DMPEOF ;IF EOF - LIGHT BIT
CAIG J,TOPBLK ;BLOCK LEGAL?
JRST READBC ;GO READ BLOCK NUMBER
TROA S,IOBKTL ;LIGHT ERROR BIT
;EOF BEFORE ALL DATA IS IN - DUMP MODE
DMPEOF: TRO S,IODEND ;LIGHT EOF BIT
JRST DMPTH2 ;GIVE UP TAPE
SVADER: PUSHJ P,DMPTH2 ;GIVE UP CONTROL
JRST ADRERR## ;TYPE ERROR MESSAGE
;COME HERE ON ERROR
ERRS: MOVEI T1,.ERDTA ;SAY DTA ERROR TO DAEMON
HRL T1,F ;PUT DDB ADDRESS IN LH FOR DAEMON
SKIPE [M.DTAE##] ;WANT DECTAPE ERROR LOGGING?
PUSHJ P,DAEERR## ;CALL DAEMON TO LOG ERROR
IFN CPBIT,<
TLNN S,NOBUF ;I/O DIRECT TO USER?
JRST ERRS1 ;NO
MOVE M,SVPNTR##(W) ;YES. RESET POINTERS
PUSHJ P,DT3XCH ;SAVE AC'S AND GET BOUNDRIES
PUSHJ P,NXCMR## ;GET FIRST IOWD AGAIN
PUSHJ P,DT3XCH ;RESTORE AC'S
JUMPE T1,PERMER ;MUST HAVE OVERWRITTEN THE LIST
MOVEM M,USPNTR##(W) ;ADDR OF CURRENT IOWD
HLROM T1,BLKCNT##(W) ;START WORD COUNT OVER
MOVEM T1,PNTR##(W) ;SAVE FIRST IOWD
>; END IFN CPBIT
ERRS1: AOS T1,ERRCNT##(W) ;BUMP COUNT
XCT DTSCNI##(W) ;DO A CONI DAS,T4
TRNN T4,40000 ;IF ILLEGAL OP DONT RETRY
CAILE T1,DTTRY## ;ENOUGH REREADS?
JRST PERMER ;YES. PERMANENT ERROR
JRST FNDBL2 ;NO. TRY AGAIN
;PERMANENT ERROR
PERMER: SKIPL BLOCK##(W) ;IF BAD BLOCK # LIGHT IODTER
TRNE T4,400000
TRO S,IODTER ;PARITY
TRNN T4,10000
TRNE T4,200000
TRO S,IODERR ;MISSED DATA
TRNE T4,40000
TRO S,IOIMPM ;ILLEGAL OP
TLNE S,DMPMOD ;DUMP MODE?
JRST DMPTHR ;YES. NOT THROUGH YET
TLNN S,IO+RWDIR+SINGL
JRST DTAIN2
REWDUN: PUSHJ P,SETIOD## ;NO. TAKE OUT OF IO WAIT
TLCN S,RWDIR+SINGL ;DIRECTORY OPERATION?
JRST THRUTP ;NO. RETURN TO USER
TLZN S,RWDIR+SINGL ;YES. UTPCLR ?
JRST THRUTP ;YES. IGNORE ERROR
PUSHJ P,THRUTP ;NO. STOP TAPE
MOVSI T1,DVDIRIN ;CLEAR DIRECTORY IN CORE BIT
ANDCAM T1,DEVMOD(F)
BDDIR: LDB J,PJOBN## ;NUMBER OF OFFENDING JOB
JUMPE J,CPOPJ##
JRST BADDIR## ;GO PRINT ERROR MESSAGE
SLPNTR: POINT 7,DEVOAD(F),6
SUBTTL DECTAPE KONTROLLER SCHEDULING ROUTINES
;HERE TO WAIT/FREE FOR DECTAPE KONTROLLER POINTED TO BY W
DXWAIT: PUSH P,J ;SAVE J
LDB J,PJOBN## ;GET JOB #
HRLM W,JBTDTC##(J) ;WHO WE WANT
CPLOCK (SCD) ;RUN WITH THE SCHEDULAR INTERLOCK
AOSG DTXREQ##(W) ;SAY WE WANT IT
DXWAI1: SKIPE DTXWAT##(W) ;ANYONE OWN IT?
JRST WAITDX ;YES, HAVE TO WAIT FOR IT
MOVEM J,DTXWAT##(W) ;SET WE OWN IT
CPUNLK (SCD)
JRST JPOPJ## ;RETURN
WAITDX: CPUNLK (SCD)
MOVEI T1,DTQ##
DPB T1,PJBSTS## ;MARK JOB WAITING
PUSHJ P,DTWAIT## ;WAIT FOR IT
JRST JPOPJ## ;REESTORE J AND RETURN
;HERE TO GIVE UP ANY CONTROLLER WE MIGHT OWN
;J CONTAINS JOB NUMBER
DTXFRE::HLRZ W,JBTDTC##(J) ;ONE WE OWN
JUMPE W,CPOPJ##
PUSH P,T1 ;SAVE T1
PUSH P,J
JRST DXFRE1
DXFREE: PUSH P,T1
PUSH P,J
LDB J,PJOBN##
DXFRE1: HRRZS JBTDTC##(J)
SOS DTXREQ##(W) ;ONE LESS WAITER/HOLDER
SETZM DTXWAT##(W) ;CLEAR OWNING JOB
PJRST SRFRDT## ;TREAT LIKE DA/AU
;HERE FROM SCHEDULAR TO SEE IF WE OWN A DECTAPE CONTROLLER
;SKIP RETURN IF DO, NONSKIP IF DON'T
OWNDTC::PUSH P,T1
HLRZ T1,JBTDTC##(J) ;CONTROLLER WE THINK WE OWN
JUMPE T1,TPOPJ## ;DON'T OWN IT
CAMN J,DTXWAT(T1) ;REALLY OWN IT?
AOS -1(P) ;NOPE
JRST TPOPJ##
;HERE FROM SCHEDULAR TO UNWIND A DECTAPE
;ENTER WITH JOB WANT TO RUN IN J, EXIT WITH JOB OWNING HIS DECTAPE
;KONTROLLER IN T3
UNWDTC::HLRZ T3,JBTDTC##(J)
JUMPE T3,CPOPJ## ;DOESN'T WANT ONE? PUNT
MOVE T3,DTXWAT(T3) ;GET JOB #
POPJ P,
;HERE TO GIVE JOB DECTAPE KONTROLLER AT SCHEDULAR LEVEL
SCDDT:: HLRZ T3,JBTDTC##(J) ;ONE HE WANTS
JUMPE T3,CPOPJ## ;?
HRL T3,DTXWAT##(T3) ;RESOURCE
TLNE T3,-1 ;STILL FREE?
POPJ P, ;NOPE
MOVEM J,DTXWAT##(T3) ;WE NOW OWN IT
JRST CPOPJ1##
SUBTTL DEVOP. UUO
;CALLED FROM UUOCON WITH DEVOP. FUNCTION CODE IN T1, DDB ADDRESS IN F
DVPDTA: MOVSI T2,-DVPTBL ;-VE LENGTH OF TABLE
DVPDT1: HLRZ T3,DVPTAB(T2) ;GET ENTRY FROM TABLE
CAIE T3,(T1) ;MATCH?
AOBJN T2,DVPDT1 ;NO, LOOP
JUMPGE T2,ECOD2## ;JUMP IF NO MATCH
HRRZ T2,DVPTAB(T2) ;GET DISPATCH ADDRESS
PJRST (T2) ;CALL THE ROUTINE
DVPTAB: XWD 1006, DVPRDI ;READ DECTAPE INFO
XWD 2006, DVPSDI ;SET DECTAPE INFO
DVPTBL==.-DVPTAB ;LENGTH OF TABLE
;READ DECTAPE INFO (REELID, READ/WRITE COUNTS)
DVPRDI: MOVE T1,DTXRID##(F) ;GET REELID
PUSHJ P,PUTWR1## ;STORE IT
JRST RTM1## ;ADDRESS CHECK
MOVE T1,DTXWRD##(F) ;GET WORDS READ
PUSHJ P,PUTWR1## ;STORE IT
JRST RTM1## ;ADDRESS CHECK
MOVE T1,DTXWWT##(F) ;GET WORDS WRITTEN
PUSHJ P,PUTWR1## ;STORE IT
JRST RTM1## ;ADDRESS CHECK
JRST CPOPJ1## ;SKIP RETURN
;SET DECTAPE REELID (CLEARS READ/WRITE COUNTS)
DVPSDI: PUSHJ P,PRVJ## ;PRIVILEGED JOB?
SKIPA ;YES
JRST ECOD1## ;NOPE
PUSHJ P,GETWR1## ;GET REELID
JRST RTM1## ;ADDRESS CHECK
MOVEM T1,DTXRID##(F) ;SAVE NEW REELID
SETZM DTXWRD##(F) ;CLEAR READ AND
SETZM DTXWWT##(F) ; WRITE COUNTS
JRST CPOPJ1## ;SKIP RETURN
SUBTTL THE END
$LIT
DTAEND: END