Trailing-Edge
-
PDP-10 Archives
-
AP-D543V_SB
-
uuocon.mac
There are 20 other files named uuocon.mac in the archive. Click here to see a list.
TITLE UUOCON - UUO HANDLER AND UUO+IO ROUTINES - V161132
SUBTTL /CHW/TL/RCC/CMF/PH/GDR/DAL/EVS/TW/JMF/DRT 31 OCT 78
SEARCH F,S
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
XP VUUOCN,161132
;THIS MACRO PUTS VERSION NO. IN STORAGE MAP AND GLOB
UUOCON::ENTRY UUOCON ;ALWAYS LOAD UUOCON(IF LIB SEARCH)
IFNDEF MAXCAL,<XP MAXCAL,56>
;DEFINE HIGHEST CALLI UUO WHICH HAS
; CORRESPONDING CALL UUO
; TABLE OF CONTENTS FOR UUOCON
;
;
; 1. UUO DISPATCH ROUTINE
; 2. CALL & CALLI UUO'S
; 3. EXIT & SETPOV UUO'S
; 4. RESET & APRENB UUO'S
; 5. MISC. ACCOUNTING UUOS (JOBNO,JOBTIM,DATE & MSTIME)
; 6. SLEEP SERVICE FOR SLEEP UUO, DTA, MTA AND SCNSER
; 7. PEEK UUO
; 8. POKE. UUO
; 9. CALLS TO SEGCON FOR SETUWP AND REMAP
; 10. TRIVIAL UUOS (LIGHTS, TIMER AND SWITCH)
; 11. DEVCHR AND DEVSIZ UUO'S
; 12. GETPPN AND DEVPPN UUO'S (ALSO RTZER)
; 13. IONDX. UUO
; 14. SUBROUTINE TO FIND A DDB GIVEN ITS IO INDEX
; 15. MVBFH. UUO -- MOVE BUFFER HEADERS
; 16. DEVSTS, DEVLNM, DEVRST, AND DEVURS UUO'S
; 17. SETDDT, WAIT AND GETLIN CALLI'S ; WAIT2 AND GETPPL
; 18. LOGIN, LOGOUT AND ATTACH UUO'S
; 19. GETTAB UUO
; 20. SETNAM & CNGPPN UUO'S
; 21. DEVNAM UUO
; 22. REAL-TIME AND HIBWAKE FEATURE
; 23. DAEMON UUO'S AND ROUTINES
; 24. CLOSE UUO
; 25. INBUF & OUTBUF UUO'S
; 26. OPEN & INIT UUO'S
; 27. COMMON PART OF LOOKUP AND ENTER
; 28. COMMON PART OF RENAME, USETI/O, UGETF AND UTPCLR
; 29. COMMON PART OF INPUT AND OUTPUT UUO'S
; 30. RELEASE UUO
; 31. STATUS SETTING AND GETTING UUO'S
; 32. ROUTINES TO ADVANCE BUFFERS
; 33. DUMP MODE COMMAND LIST PROCESSING ROUTINES
; 34. DDB SCAN LOGIC
; 35. BUFFER RING BUILDER & CLEARER
; 36. RANDOM SUBROUTINES FOR I/O
;THE CALL UUO ROUTINES AND THE IO UUO ROUTINES
;SOME UUO DO DISPATCH TO OTHER ROUTINES OUTSIDE OF UUOCON
;SYSTEM UUOS(40-77) FIRST SAVE THE USERS ACS IN RELATIVE LOC 0-17
;THEN THE FOLLOWING ACS ARE LOADED UP BEFORE DISPATCHING:
; P ;PUSHDOWN LIST IN CURRENT JOB DATA AREA
; R ;CURRENT JOB RELOCATION IN RH,PROTECTION IN LH
; M ;THE CONTENTS OF LOC 40 WITH R IN INDEX FIELD
; ;SO THAT RELOCATION CAN BE DONE FOR PICKING UP ARGUMENTS
; EXCEPT THAT ON A CALL OR CALLI UUO, THE ADDRESS IS
; MODIFIED TO BE THE AC OF THE UUO,FOR
; PICKING UP ARGUMENTS.
; F ;ADR. OF DEVICE DATA BLOCK
; S ;DEVICE IO STATUS WORD
; T1 ;(CALLI) CONTENTS OF AC
; T4 ;ADR. OF DEVICE SERVICE ROUT. DISPATCH TABLE
; P1 ;THE USER IO CHANNEL(AC FIELD) OF UUO
;LH BIT 0=1 (PHONLY) IF ONLY PHYSICAL DEVICE WANTED
; IE NO LOGICAL NAME SEARCH
;RETURN IS PUSHED ON END OF PD LIST
;THEN IF CALL WAS FROM USER MODE, THE UUO ROUTINE IS CALLED
;WITH A PUSHJ, SO THAT ALL UUO ROUTINE RETURN WITH A POPJ P,
;WHICH WILL RETURN CONTROL TO UUOCON WHICH WILL RESTORE USERS
;ACS AND RETURN TO HIM
;IF THE CALL IS FROM EXEC MODE, THE UUO ROUTINE IS CALLED
;BY DOING JUST A JRST, WHEN THE UUO ROUTINE RETURNS WITH
;A POPJ, IT WILL RETURN TO THE EXEC WITHOUT RESTORING
;ANY ACS
; CONTROL MAY ALWAYS BE RETURNED BY EXECUTING A
; POPJ P,
; WHICH WILL RESTORE THE ACS, APR BITS, AND RETURN.
; THE UUO HANDLER IS PURE IF THE FOLLOWING RESTRICTIONS ARE OBSERVED.
; RESTRICTIONS: UUOS CANNOT BE CALLED BY INTERRUPT SERVICE ROUTINES.
;ALL UUO'S SHOULD PRESERVE THE PRESERVED AC'S P1-P4
SUBTTL UUO DISPATCH ROUTINE
;HERE FROM COMMON WITH ACS SAVED IF KA10. NO NEED TO SAVE ACS
; ON A KI10 SINCE THE MONITOR USES AC BLOCK 0 AND THE USER USES
; AC BLOCK 1.
UUOSY1::MOVE M,MPTRAP## ;GET THE UUO INTO AC(M)
; (CHECK THIS BEFORE PUSHING ON STACK WHICH WOULD
; DESTROY VALUABLE INFO IN CRASH IF FROM EXEC MODE)
MOVE J,JOB## ;SET UP J IN CASE UUOERR
; (GIVRES EXPECTS J SET UP)
TLNN M,740000 ;SYSTEM UUO?
JRST UUOERR## ;NO, 0-37 ARE ILLEGAL, PRINT ERROR
PUSH P,UUO0## ;SAVE RETURN ON PUSH DOWN LIST
IFN FTMS,< PUSHJ P,MSTUUO## ;SET THIS JOB TO RUN ON MASTER ONLY DURING UUO
> ; (ALREADY CHECKED FOR ILLEGAL UUO).
IFN FTKA10,<
MOVEI P4,.C0CDB## ;CPU0'S CDB
>
;UUOS FROM SLAVE ENTER HERE AFTER RESCHEDULED ON MASTER
MPUUO:: PUSHJ P,FNDPDS## ;FIND JOB'S PDB
IFN FTACCT,<
AOS .PDUUC##(W) ;COUNT THE UUO
>
TLO M,R ;SET FOR RELOCATION
LDB T2,[POINT 9,M,8];PICK UP UUO OP CODE
CAIL T2,100 ;ILLEGAL INSTRUCTION?
JRST ILLINS## ;YES, STOP JOB AND PRINT ERROR
LDB P1,PUUOAC## ;SETUP USER DEVICE CHANNEL NUMBER
IFN FTVM,<
SKIPE F,USRJDA##(P1) ;GET ADRESS OF DEVICE DATA BLOCK
>
IFE FTVM,<
MOVEI F,.CPJDA##(P4) ;ADDRESS OF CHANNEL TABLE ON THIS CPU
ADDI F,(P1) ;PLUS THE CHANNEL NUMBER
SKIPE F,(F) ;IS THE A DDB?
>
IFN FTVM,<
CAMLE P1,USRHCU##
>
IFE FTVM,<
CAMLE P1,.CPHCU##(P4) ;IS IT LESS THAN OR EQUAL TO HIGHEST
; USER IO CHANNEL IN USE FOR CURRENT JOB?
>
JRST NOCHAN ;CHANNEL NOT ASSIGNED
DISP3: MOVE S,DEVIOS(F)
MOVE T4,DEVSER(F) ;SETUP IO SERVICE DISPATCH
; TABLE ADDRESS
CAIL T2,LNGUUO ;LONG DISPATCH TABLE UUO?
JRST DISP1 ;YES
DISP0: ROT T2,-1 ;DIVIDE UUO OPCODE BY 2, SAVE REMAINDER
MOVE U,UUOTAB-20(T2);GET DISPATCH TABLE ENTRY
IFN FTVM!FTMS,<
MOVE T1,M ;ADR INTO T1 FOR UUOCHK
MOVE T3,CHKTAB-20(T2);GET CHECK-BITS FOR THE UUO
>
DISP2: JUMPL T2,DISP2A ;WAS UUO ODD?
MOVS U,U ;NO, USE LH OF DISPATCH ENTRY
MOVSS T3
DISP2A:
IFN FTVM,<
TRNE T3,UU.MSK ;CHECK ARGUMENTS FOR VALIDITY?
PUSHJ P,UUOCHK## ;YES (DONT ALLOW PAGE FAULT IN UUO PROCESSING)
>
MOVE T2,(P) ;UUO FROM SYSTEM?
TLNN T2,(XC.USR)
JRST (U) ;YES
IFN FTPI,<
PUSHJ P,ANYUUO## ;CALL PSISER SINCE THIS IS A FUNNY
; CONDITION
;***NOTE: THIS ROUTINE SKIPS TO ABORT THE UUO. IT MUST BE PRIOR TO THE
; PUSHJ P,(U) SO IT WILL SKIP INTO UUOXIT
>
;DISPATCH TO UUO ROUTINE
;THE FOLLOWING CODE IS EXECUTED ON ALL RETURN TO USER PROGRAMS
;BUT IS NEVER EXECUTED ON RETURNS FROM EXEC UUOS(SAVGET)
PUSHJ P,(U) ;NO, FROM USER. ALL
; UUO ROUTINES RETURN WITH POPJ
JRST USRXIT ;NO SKIP RETURN TO USER
USRXT1:
IFE FTVM,<
AOS JOBPD1##(R)
>
IFN FTVM,<
PUSHJ P,INCPD1##
>
USRXIT::
IFN FTNET,<
JUMPE F,UUONET ;NO DDB
HRRZ T1,DEVSER(F) ;GET NETWORK DDB BIT
CAIE T1,NETDSP## ;IS IT
JRST UUONET ;NO, IGNORE
MOVEI T1,ASSCON!ASSPRG ;IS THE DDB ASSIGNED OR INITED
TDNN T1,DEVMOD(F) ;CHECK
PUSHJ P,ZAPNET## ;NO, REMOVE THE DDB
UUONET:
> ;END FTNET
IFN FTMS,<
SKPCPU (0) ;ON CPU0?
JRST USPXIT## ;NO, SEE IF CPU1 JOB SHOULD BE STOPPED
>
IFE FTVM,<
SKIPE T2,USREPL## ;DOES THIS USER HAVE EXEC CORE FOR EXTENDED PD LIST?
; (POSSIBLE IF PDL OV DURING UUO)
PUSHJ P,GIVEPL## ;YES, GIVE IT BACK (SEE CORE1)
> ;END IFE FTVM
MOVSI T1,37 ;GET MASK OF IR+IND FIELDS
IORM T1,MPTRAP## ;OR INTO 40 SO UUO WATCHERS SEE IT
MOVE J,JOB## ;CURRENT JOB NUMBER
IFN FTMS,< PUSHJ P,DPXST## ;CLEAR BIT SP.NR1 SO CAN'T START JOB ON CPU0
; IF CPU0 NOT IN JOB'S CPU SPECIFICATION
PUSHJ P,UXITMP## ;OR IS THIS JOB UNRUNABLE ON MASTER CPU
JRST USRXT2 ;YES, GO DO A RESCHEDULE
>
MOVE T1,JBTSTS##(J) ;JOB STATUS WORD
TDNN T1,[XWD STOPIO!JXPN!CNTRLC,JS.DEP!JS.MPE] ;IS MONITOR TRYING TO STOP THIS USERS
; IO OR IS HE TRYING TO STOP HIS JOB
; (BY TYPING ^C WHILE HE WAS IN MONITOR)?
; OR IS HE EXPANDING (JXPN)
; OR HAD ERROR AND IS IN DAEMON ERROR PAUSE?
; OR MEM PAR ERR (WHILE IN MONITOR BUT BAD ADR
; PROVED TO BE IN USER MODE)
SKIPE TIMEF## ;NO. HAS CLOCK TICKED WHILE IN MONITOR?
JRST USRXT2 ;YES, GO CALL SCHEDULER
CAME J,FORCEF## ;NO, BEING FORCED WITH RESOURCE(WON'T HAVE NOW)
SKIPE .C0RTF## ;NO, SHOULD WE DO A HIGH PRIORITY RESCHEDULE
; ONLY SET FOR CPU0 UNTIL RTTRP UUOS CAN BE HANDLED ON CPU1
;------ NOTE - 'UUODON' MUST LABEL THE PC STORED BY THIS PUSHJ
;USED FOR CONTROL C INTERCEPT TO DETECT USER STOPPED ON THIS CALL TO SCHED
USRXT2: PUSHJ P,USCHD1## ;YES, GO CALL SCHEDULER
UUODON:: ; SAVE CURRENT JOB NO (J)
;---------------- ; NOTE: USCHD1 POPS PUSHJ PC INTO JOBPC
; WHEN RESCHEDULING JOB
;HERE TO RETURN TO USER - CHECK IF USER TRAP PENDING
USRRET::
IFN <FTKI10!FTKL10>&FTSET,<
MOVEI T1,JS.ABP ;EXEC MODE ADDRESS BREAK BIT
TDNE T1,JBTST2##(J) ;DID ONE OCCUR DURING THIS UUO?
PUSHJ P,EXCABK## ;YES, GO PROCESS IT
>
IFN FTPI,<
XCT NOPISK## ;SKIP IF NO INTERRUPTS BECAUSE USER
; IS NOT ENABLED FOR SOFTWARE INTERRUPTS.
XCT @JBTPIA##(J) ;EXECUTE THE USER'S PENDING TRAP
; INSTRUCTION.
UUOPSI:: ;PSI EXPECTS THIS TO BE THE PC STORED BY
; PUSHJ XCT ABOVE.
XCT NOPISK##
XCT @JBTPIA##(J)
> ;END FTPI
MOVE T1,JBTSTS##(J) ;STATUS WORD FOR CURRENT USER
; ON THIS CPU
TRNN T1,UTRP ;SEE IF TRAP PENDING
JRST USRXNT ;NO--PROCEED BELOW
;HERE WHEN TRAP SET UP WHILE JOB WAS DOING A UUO.
;TYPE OF TRAP IS IN .JBFDV:
; -1 IF .JBINT TRAP (E.G., ^C)
; 0,,ADDR IF START AT ADDR (E.G., .DDT)
MOVE T2,(P) ;GET RETURN PC
IFN FTCCIN,<
SKIPGE T4,JOBFDV##(R) ;GET NEW PC
JRST USRXJI ;NO--GO DO .JBINT
>
IFE FTCCIN,<
MOVE T4,JOBFDV##(R) ;GET NEW PC
>
MOVEM T2,JOBOPC##(R) ;STORE INTERRUPTED PC
HRRM T4,(P) ;STORE NEW PC
IFN FTCCIN,<
JRST USRXCT ;AND GO FINISH INTERRUPT
USRXJI: MOVEI T4,0 ;CLEAR BITS
PUSHJ P,CHKINT## ;SEE IF INT BLOCK OK
JRST USRXCT ;NO--JUST CLEAR TRAP
PUSHJ P,DOINT## ;YES--SWITCH PC
>
USRXCT: MOVEI T1,UTRP ;CLEAR
ANDCAM T1,JBTSTS##(J) ; TRAP FLAG
;HERE TO RESTORE USER HARDWARE STATE AND JUMP TO USER
USRXNT:
IFN FTMS,< SKPCPU (0) ;MASTER?
JRST USPRET## ;NO, GO EXIT TO USER FROM SLAVE DEPENDENT CODE
>
JRST UMPRET## ;YES, GO EXIT TO USER FROM MASTER DEPENDENT CODE
NOCHAN:
IFN FTVM,<
SKIPL USRHCU## ;SAVE/SET IN PROGRESS?
CAMG P1,USRHCU## ;NO, MAKE SURE LEGAL CHANNEL
>
IFE FTVM,<
SKIPL .CPHCU##(P4) ;SAVE/GET IN PROGRESS (F POINTS TO DDB)
CAMG P1,.CPHCU##(P4) ;NO, USER CHANNEL NO. GREATER THAN HIGHEST INITED
>
SKIPA ;DON'T ZERO F - IT POINTS TO A DDB
MOVEI F,0 ;INDICATE NO DDB
MOVSI T3,(XC.USR)
CAIE T2,70 ;YES,IS IT CLOSE OR RELEASE?
CAIN T2,71 ;CLOSE AND RELEASE ALWAYS LEGAL
; EVEN THOUGH NO DEVICE ASSIGNED
JRST NOOP ;YES, DO NO-OP FOR EXEC OR USER
TDNE T3,(P) ;UUO FROM USER?
;IF FROM EXEC, PROBABLY SAVGET
; WHICH SETS USRCHN NEG. IN LH
CAIGE T2,IOUUO ;YES, IS THIS AN IO UUO?
JRST DISP3 ;NO, GO DISPATCH
JRST IOIERR## ;NO, PRINT IO TO UNASSIGNED CHANNEL
; AND STOP JOB
NOOP: TDNE T3,(P) ;YES,IS UUO FROM USER?
JRST USRXIT ;YES, RETURN TO HIM (RESTORE ACS)
POPJ P, ;NO, RETURN TO EXEC (DO NOT RESTORE ACS)
DISP1: MOVE T1,DEVMOD(F) ;LONG DISPATCH TABLE UUO
IFN FTSPL,<
SKIPL DEVSPL(F) ;LONG DISPATCH TABLE IF SPOOLED
>
TLNE T1,DVLNG ;DOES THIS DEVICE HAVE A LONG
; DISPATCH TABLE?
JRST DISP0 ;YES, DISPATCH
CAIGE T2,76 ;NO, IS UUO LOOKUP OR ENTER?
JRST USRXIT ;NO, RETURN TO USER
HRRI T1,DVIN ;YES, TEST IF DEVICE LEGAL
CAIN T2,77 ;LOOKUP?
HRRI T1,DVOUT ;NO, TEST FOR OUTPUT DEVICE (ENTER)
TLNE T1,(T1) ;IF LOOKUP, TEST FOR INPUT DEVICE (DVIN)
JRST USRXT1 ;DEVICE AND FUNCTION AGREE, SKIP RETURN
PUSHJ P,GETWD1## ;NOT AGREE, GET E+1
HRRI T1,0 ;ERROR CODE 0, FILE-NOT-FOUND SHOULD NOT MESS UP UPDATES
PUSHJ P,PUTWDU## ;PUT BACK IN E+1
JRST USRXIT ;AN NON SKIP RETURN TO USER
;TABLE OF UUO DISPATCH ADDRESSES
;IN FORMAT:
; XWD 40,41
; XWD 42,43
; .
; XWD 76,77
XALL
UUOTAB: UCALL,,UINIT ;(40,41)CALL,INIT
UUOERR##,,UUOERR## ;(42,43)FIVE UUOS FOR EACH INSTALLATION
UUOERR##,,UUOERR## ;(44,45)TO DEFINE AS THEY SEE FIT
UUOERR##,,UCALLI ;(46,47),CALLI
UOPEN,,TTYUUO## ;(50,51)OPEN, TTCALL
UUOERR##,,UUOERR## ;(52,53)
UUOERR##,,URENAM ;(54,55),RENAME
XP IOUUO,55 ;LOWEST IO UUO(RENAME)
TIN,,TOUT ;(56,57)IN,OUT
SETIOS,,USTATO ;(60,61)SETSTS,STATO
USTATS,,USTATZ ;(62,63)GETSTS,STATZ
UINBF,,UOUTBF ;(64,65)INBUF,OUTBUF
UIN,,UOUT ;(66,67)INPUT,OUTPUT
CLOSE1,,RELEA1 ;(70,71)CLOSE,RELEASE
XP LNGUUO,72 ;LOWEST LING DISPATCH TABLE UUO
UMTAPE,,UDGF ;(72,73)MTAPE,GETF
UDSI,,UDSO ;(74,75)SETI,SETO
UDLK,,UDEN ;(76,77)LOOKUP,ENTER
;UUOS 42, 43, 44, 45, AND 46 ARE FOR CUSTOMERS TO DEFINE AS THEY PLEASE
;UUOS 40, 41 AND 47 THROUGH 77 ARE DEFINED BY DIGITAL
;UUOS 51,52,53 AND 54 ARE RESERVED FOR EXPANSION BY DIGITAL
IFN FTVM!FTMS,<
;TABLE OF CHECK-BITS FOR UUOS
CHKTAB::UU.EA,,3 ;CALL,INIT
0,,0 ;42,43
0,,0 ;44,45
0,,UU.CP1 ;46,CALLI
UU.EA+3,,UU.EA ;OPEN,TTCALL
0,,0 ;52,53
0,,UU.LER ;54,RENAME
0,,0 ;IN,OUT
0,,UU.CP1 ;SETSTS,STATO
UU.CP1,,UU.CP1 ;GETSTS,STATZ
0,,0 ;INBUF,OUTBUF
0,,0 ;INPUT,,OUTPUT
0,,0 ;CLOSE,,RELEASE
0,,0 ;MTAPE,UGETF
0,,0 ;USETI,USETO
UU.LER,,UU.LER ;LOOKUP,ENTER
>
SUBTTL CALL & CALLI UUO'S
; CALLING SEQUENCE
; CALL D,[SIXBIT/NAME/]
; WHERE NAME IS THE NAME OF A SYSTEM ROUTINE.
; IF NO SYSTEM ROUTINE WITH THE SPECIFIED NAME IF FOUND, THIS ROUTINE
; EXITS TO UUOERR.
;CONTENTS OF USER AC PLACED IN AC T1,UUO SET TO POINT
;TO USER AC, R IN LH.
;J SET TO JOB NUMBER
UCALL: PUSHJ P,GETWDU## ;SET T1 FROM CONTENTS OF EFFECTIVE ADDRESS OF
; UUO FROM EITHER HIGH OR LOW SEG
; DO NOT RETURN IF ERROR
; SET J TO CURRENT JOB NO.
MOVNI T2,UCLLEN+CCLLEN ;LENGTH OF TABLE
CAME T1,CCLTAB+UCLLEN+CCLLEN(T2) ;SEARCH SYSTEM ROUTINE NAME TABLE
AOJL T2,.-1
HRRI T2,UCLLEN(T2)
JUMPGE T2,CPOPJ## ;IF NOT FOUND, NO. OF UUO
HRRM T2,M ;STORE INDEX IN UUO, JUST AS IF USER HAD DONE CALLI UUO
;FALL INTO CALLI ON NEXT PAGE
;CALL UUO FALLS IN HERE
;CALLI UUO - CALL IMMEDIATE
;CALLI D,E
;WHERE E IS RELATIVE INDEX IN CALL TABLE
UCALLI::MOVE T1,T2 ;SAVE USER/EXEC BIT
HRRE T2,M ;GET CALLI NUMBER(POS.=DIGITAL,NEG.=CUSTOMER DEFINED)
IFN FTPHYO,<
JUMPL T2,UCALL1 ;IF ARGUMENT IS POSITIVE,
TRZE T2,UPHNLY ;IS BIT 19=1?
HRLI P1,PHONLY ;YES, PHYSICAL DEVICES ONLY
JRST UCALL2
UCALL1: TRON T2,UPHNLY ;ARGUMENT NEG, IS BIT 19=0?
HRLI P1,PHONLY ;YES, PHYSICAL ONLY
> ;END CONDITIONAL ON FTPHYO
UCALL2: CAML T2,MCCLEN ;MORE NEGATIVE THAN MOST NEGATIVE CUSTOMER DEFINED UUO?
CAIL T2,UCILEN ;MORE POSITIVE THAN HIGHEST DIGITAL DEFINED CALLI?
POPJ P, ;YES, RETURN TO USER TREAT AS NO-OP SO
; PROGRAMS AHEAD OF MONITOR WILL STILL
; RUN WITHOUT ERROR MESSAGE
TLNE T1,(XC.USR) ;NO, UUO WAS FROM MONITOR?
POP P,(P) ;NO, REMOVE RETURN
HRR M,P1 ;UUO AC FIELD
PUSHJ P,GTWST2## ;PICK UP CONTENTS OF USER AC
ROT T2,-1 ;DIVIDE BY 2 AND SAVE REMAINDER
MOVE U,UCLJMP(T2) ;GET DISPATCH TABLE ENTRY
IFN FTVM,<
MOVE T3,CHKTBC(T2) ;GET CHECK-BITS
>
JRST DISP2 ;AND GO DISPATCH
;CALL UUO DISPATCH TABLE
;NEW UUO'S MUST BE ADDED AT END SINCE CALLI DEPENDS ON
;POSITION IN TABLE, CUSTOMERS SHOULD ADD UUO'S IN CNAMES MACRO SO CALLI ADDRESS
;WILL BE NEGATIVE. IN THIS WAY BOTH DIGITAL AND ITS CUSTOMERS CAN ADD UUO'S
;WITHOUT CONFLICT, DIGITAL GOING POSITIVE, CUSTOMERS GOING NEGATIVE.
; (ALSO, TOWARD TOP OF PAGE)
DEFINE CNAMES <
IFN FTPATT,<
X CPOPJ,CPOPJ## ;(-3) PLACE FOR CUSTOMERS
; TO PATCH UUOS
X CPOPJ,CPOPJ## ;(-2)
>
X LIGHTS,LIGHTS,UU.CP1 ;(-1) SET LIGHTS (EXAMPLE
; OF CUSTOMER DEFINED
; UUO)
>
DEFINE NAMES,<
X RESET,RESET ;(0)RESET IO
X DDTIN,DDTIN##,UU.EA+25 ;(1)EXT-GET DDT CHAR.
X SETDDT,SETDDT,UU.CP1 ;(2)SETDDT LOC IN PROTECTED
; JOB DATA
X DDTOUT,DDTOUT##,UU.EA+25 ;(3)EXT:SEND DDT CHAR.
X DEVCHR,DVCHR ;(4)DEVICE CHARACTISTICS
X DDTGT,CPOPJ##,UU.CP1 ;(5)GET DDT MODE
X GETCHR,DVCHR ;(6)DEVICE CHAR.(DIFF. NAME)
X DDTRL,CPOPJ##,UU.CP1 ;(7)RELEASE DDT MODE
X WAIT,WAIT ;(10)WAIT TILL DEVICE INACTIVE
X CORE,CORUUO## ;(11)CORE UUO
X EXIT,EXIT ;(12)EXIT
X UTPCLR,UTPCLR ;(13)CLEAR DEC TAPE DIRECTORY
;
X DATE,DATE,UU.CP1 ;(14)GET DATE
X LOGIN,LOGIN,UU.MEA ;(15)LOGIN
X APRENB,APRENB ;(16)ENABLE APR FOR TRAPPING
X LOGOUT,LOGOUT ;(17)LOGOUT
X SWITCH,SWITCH,UU.CP1 ;(20)RETURN DATA SWITCHES
X REASSI,REASSI## ;(21)REASSIGN DEVICE TO ANOTHER
; JOB
X TIMER,TIMER,UU.CP1 ;(22)RETURN JIFFY CLOCK TIME
X MSTIME,MSTIME,UU.CP1 ;(23)RETURN TIME OF DAY IN
; MS
;CONTINUED ON NEXT PAGE
X GETPPN,GETPPN,UU.CP1 ;(24)RETURN PROJECT-PROGRAMMER
; NUMBER
X TRPSET,TRPSET,UU.LEA ;(25)SET PI TRAP LOC, AND
; USER IO
X TRPJEN,UUOERR## ;(26)DISMISS INTERRUPT TO
; EXEC MODE(SUPERCEDED
; BY UJEN)
X RUNTIM,JOBTIM,UU.CP1 ;(27)RETURN TOTAL JOB RUNNING
; TIME
X PJOB,JOBNO,UU.CP1 ;(30)RETURN JOB NUMBER
X SLEEP,SLEEP ;(31)SLEEP FOR N SECONDS,
; THEN RETURN TO USER
X SETPOV,SETPOV,UU.CP1 ;(32)SET PUSH DOWN OVERFLOW
; TRAP
X PEEK,UPEEK,UU.CP1 ;(33)TO PEEK AT CERTAIN MONITOR
; PARAMETERS
X GETLIN,GETLN,UU.CP1 ;(34) GET TTY LINE NUMBER
X RUN,URUN##,UU.EA+6 ;(35) RUN DEV:FILE
X SETUWP,SETUWP ;(36) SET OR CLEAR USER MODE
; WRITE PROTECT
X REMAP,REMAP ;(37) REMAP TOP OF LOW SEGMENT
; INTO HIGH SEG
X GETSEG,UGTSEG##,UU.EA+6 ;(40) GET SHARABLE HIGH SEG
X GETTAB,GETTAB,UU.CP1 ;(41) GET EXEC ADDRESS OF
; A JOB TABLE
X SPY,USPY## ;(42) SET HIGH SEG TO BE
; PHYSICAL CORE
X SETNAM,SETNAM,UU.CP1 ;(43) SETNAME OF THIS PROGRAM
;LAST CALLI IN 4.50
X TMPCOR,TMPUUO##,UU.EA ;(44) TEMPORARY FILE STORAGE
; UUO (CCL)
X DSKCHR,DSKCHR##,UU.LEA ;(45) DISK CHARACTERISTICS
;LAST CALLI IN 4.72
X SYSSTR,SYSTUU## ;(46) RETURN NEXT STR IN
; SYSTEM
X JOBSTR,JOBSTR##,UU.LEA ;(47) RETURN NEXT STR IN
; JOB
X STRUUO,STRUUO##,UU.LEA ;(50) VARIOUS FUNCTION FOR
; STRS
X SYSPHY,SYSPHY##,UU.CP1 ;(51) RETURN ALL PHYSICAL
; DEVS AND UNITS IN SYSTEM
X FRECHN,CPOPJ##,UU.CP1 ;(52) RETURN 1ST FREE USER
; CHAN IN AC, STARTING
; FROM C(AC)
X DEVTYP,DVTYP ;(53) EXTENDED DEVICE CHARACTERISTICS
; AND BUFFER SIZE
;CONTINUED ON NEXT PAGE
X DEVSTS,DEVST ;(54) DEVSTS
X DEVPPN,DEVPPU ;(55) RETURN PPN FOR DEVICE
X SEEK,UUOSEK## ;(56) SEEK
;LAST CALLI IN 5.01
X RTTRP,RTTRP##,UU.EA+4 ;(57) REAL TIME TRAP
X LOCK,LOKJOB## ;(60) LOCK JOB IN CORE
X JOBSTS,UJBSTS##,UU.CP1 ;(61) RETURN STATUS OF JOB
; AND ITS PTY
X LOCATE,LOCATE##,UU.CP1 ;(62) FOR REMOTE COMM
X WHERE,WHERE## ;(63) FOR REMOTE COMM
X DEVNAM,UDEVNM ;(64) GET PHYSICAL DEVICE
; NAME
X CTLJOB,CTLJOB##,UU.CP1 ;(65) FIND CONTROLLER OF
; THIS JOB (IF BY PTY)
X GOBSTR,GOBSTR##,UU.LEA ;(66) GENERALIZED JOBSTR
; (ANY JOB'S SEARCH LIST)
;LAST CALLI IN 5.02
X FOO,CPOPJ##, ;(67) FOO
X FOO,CPOPJ##, ;(70) FOO
X HPQ,HPQ## ;(71) HIGH PRIORITY QUEUE
; UUO
IFN FTHIBWAKE,<
X HIBER,HIBUUO ;(72) HIBERNATE UUO
>
IFE FTHIBWAKE,<
X HIBER,CPOPJ##,UU.CP1 ;(72) NOP
>
X WAKE,WAKUUO ;(73) WAKE UUO
X CHGPPN,CHGPPN,UU.CP1 ;(74) CHANGE PPN
X SETUUO,SETUUO##,UU.CP1 ;(75) SET
X DEVGEN,DEVGEN ;(76) DEVICE GENERIC NUMBER
; UUO
X OTHUSR,GETPPL,UU.CP1 ;(77) SEE IF OTHER USER'S
; WITH SAME PPN AS CALLING
; JOB
X CHKACC,ACCCHK##,UU.EA+3 ;(100) ACCESS-ALLOWED UUO
X DEVSIZ,DVSIZ ;(101) RETURN BUFFER SIZE
X DAEMON,CALDAE,UU.LEA ;(102) CALL DAEMON
X JOBPEK,JOBPEK,UU.EA+2 ;(103) READ/WRITE ANOTHER
; JOB'S CORE
X ATTACH,UATTAC ;(104) ATTACH OR DETACH JOBS.
X DAEFIN,DAEFIN,UU.LEA ;(105) DAEMON FINISHED -
; RESTART USER JOB
X FRCUUO,FRCUUO,UU.LEA ;(106) FORCE COMMAND FOR
; JOB
X DEVLNM,DEVLNM ;(107) SET DEVICE LOGICAL
; NAME
;LAST CALLI IN 5.03
;CONTINUED ON NEXT PAGE
X PATH.,PTHUUO##,UU.LEA ;(110) TEST/SET FULL PATHS
; TO FILES
X METER.,METER##,UU.LEA ;(111)PERFORMANCE METERING
X MTCHR.,MTACHR## ;(112)GET MAGTAPE CHARACTERISTICS
X JBSET.,JBSET.##,UU.EA+2 ;(113)JOB SETUUO
X POKE.,POKE,UU.EA+3 ;(114)CHANGE MONITOR
X TRMNO.,TRMNO## ;(115)TERMINAL NUMBER FOR
; JOB
X TRMOP.,TRMOP##,UU.LEA ;(116)TERMINAL OPERATIONS
; UUO
X RESDV.,RESDV ;(117)RESET DEVICE OR CHANNEL
X UNLOK.,UNLOK.## ;(120)UNLOCK A LOCKED JOB
;LAST CALLI IN 5.04
X DISK.,DSKUUO##,UU.EA ;(121)RANDOM DISK FUNCTIONS
X DVRST.,DEVRST ;(122)RESTRICT DEVICE TO
; OPER ONLY
X DVURS.,DEVURS ;(123)UNRESTRICT DEVICE
;LAST CALLI IN 5.05 & 5.06
IFN FTXTC,<
X XTTSK.,XTUUO##,UU.LEA ;(124)DA28C DEPENDENT FUNCTIONS
>
IFE FTXTC,<
X XTTSK.,CPOPJ## ;(124)DA28C DEPENDENT FUNCTIONS
>
X CAL11.,CALL11##,UU.LEA ;(125)MULTI-FUNCTION CALLI
; FOR THE PDP-11
X MTAID.,MTARID## ;(126)FOR MTA ERROR REPORTING
IFN FT5UUO,<
X IONDX.,UIONDX ;(127)RETURN IO INDEX
>
IFE FT5UUO,<
X IONDX.,CPOPJ## ;(127)NOT IMPLEMENTED
>
X CNECT.,CONECT##,UU.EA+1 ;(130)CONNECT A DEVICE TO
; AN MPX CHAN
X MVHDR.,MOVHDR ;(131)MOVE BUFFER HEADER
X ERLST.,ERLST##,UU.EA+2 ;(132)ERROR LIST
X SENSE.,SENSE##,UU.LEA ;(133)SENSE
X CLRST.,CLRST##,UU.LEA ;(134)CLEAR STATUS
;CONTINUED ON NEXT PAGE
X PIINI.,PIINI##,UU.EA ;(135)INITIALIZE SOFTWARE
; INTERRUPT SYSTEM
X PISYS.,PISYS## ;(136)MANIPULATE SOFT. INTERRUPT
; SYSTEM
X DEBRK.,DEBRK## ;(137)DISMISS A SOFTWARE
; INTERRUPT
X PISAV.,PISAVE##,UU.LEA+UU.CP1 ;(140)SAVE THE PI SYSTEM
X PIRST.,PIRST##,UU.EA+UU.CAC ;(141)RESTORE THE PI SYSTEM
X IPCFR.,UIPCFR## ;(142) IPCF READ
X IPCFS.,UIPCFS## ;(143) IPCF SEND
X IPCFQ.,UIPCFQ## ;(144) IPCF QUERY
IFN FTVM,<
X PAGE.,UPAGE.##,UU.CP1 ;(145) PAGING UUOS
>
IFE FTVM,<
X PAGE.,CPOPJ##,UU.CP1
>
X SUSET.,USUSET## ;(146) SUPER USETI/O
X COMPT.,CPOPJ## ;(147) CALL TO COMPATABILITY
; PACKAGES
;LAST CALLI IN 5.07/6.01
IFN FTNSCHED,<
X SCHED.,SCHED.## ;(150) SCHEDULING UUO
>;END IFN FTNSCHED
IFE FTNSCHED,<
X SCHED.,CPOPJ##
>;END IFE FTNSCHED
X ENQ.,ENQ## ;(151) ENQUEUE
X DEQ.,DEQ## ;(152) DEQUEUE
X ENQC.,ENQC## ;(153) ENQ CONTROLLER
;CONTINUED ON NEXT PAGE
X TAPOP.,UTAPOP##,UU.LEA ;(154) TAPOP. UUO (SEE TAPSER)
IFE FT5UUO,<
X FILOP.,CPOPJ## ;(155) UNDEFINED
>
IFN FT5UUO,<
X FILOP.,FILOP,UU.LEA ;(155) FILOP. UUO
>
X CAL78.,CALL78## ;(156) FOR DAS78
X NODE.,NODE.U## ;(157) RESERVED FOR NETWORKS
X ERRPT.,ERRPT.## ;(160) ERROR REPORTING UUO FOR DAEMON
IFE FTGALAXY,<
X ALLOC.,CPOPJ## ;(161) UNDEFINED
>
IFN FTGALAXY,<
X ALLOC.,ALLOC,UU.LEA ;(161) ALLOC. UUO
>
X PERF.,UPERF. ;(162) PERFORMANCE ANALYSIS UUO
IFN FTDHIA,<
X DIAG.,DIAUUO## ;(163) DIAGNOSTIC UUO
>
IFE FTDHIA,<
X DIAG.,CPOPJ## ;(163) UNDEFINED
>
IFE FT5UUO,<
X DVPHY.,CPOPJ## ;(164) UNDEFINED
>
IFN FT5UUO,<
X DVPHY.,DVPHY. ;(164) DVPHY.UUO
>
IFN FT5UUO,<
X GTNTN.,GTNTN ;(165) GET THE NETWORK TTY NUMBER
X GTXTN.,GTXTN ;(166) GET THE -10 TTY NAME
>
IFE FT5UUO,<
X GTNTN.,CPOPJ## ;(165) NOT IMPLEMENTED
X GTXTN.,CPOPJ## ;(166) NOT IMPLEMENTED
>
IFN FTACCT,<
X ACCT.,ACCT ;(167) ACCOUNTING UUO
>
IFE FTACCT,<
X ACCT.,CPOPJ## ;(167) NOT IMPLEMENTED
>
IFN FTKL10,<
X DTE.,DTE.## ;(170) DTE. UUO
>;END IFN FTKL10
IFN FTKA10!FTKI10,<
X DTE.,CPOPJ## ;(170) NOT IMPLEMENTED
>;END IFN FTKA10!FTKI10
IFN FT5UUO,<
X DEVOP.,DEVOP,UU.LEA ;(171) DEVOP. UUO
>
IFE FTGALAXY,<
X SPPRM.,CPOPJ## ;(172) NOT IMPLEMENTED
> ;END IFE FTGALAXY
IFN FTGALAXY,<
X SPPRM.,SPPRM,UU.LEA ;(172) SPPRM. UUO
> ;END IFN FTGALAXY
;***ADD NEW CALLI'S ABOVE THIS LINE *****
IFN FTPATT,<
X CPOPJ,CPOPJ## ;2 SPARE UUO'S FOR PATCHING - DIGITAL ONLY
X CPOPJ,CPOPJ## ;ALWAYS ADD NEW UUO'S ABOVE THESE
>
;CUSTOMERS SHOULD ADD UUO'S ABOVE
;IN CNAMES MACRO RATHER THAN NAMES MACRO
; SO THAT THEIR CALLI INDICES WILL
; BE NEGATIVE
>
;GENERATE SIXBIT TABLE OF UUO NAMES
DEFINE X (A,B,C) <
<EXP SIXBIT /A/>
>
;GENERATE CUSTOMER CALL/CALLI UUO'S
MCCLEN::EXP -CCLLEN
CCLTAB: CNAMES
CCLLEN==.-CCLTAB ;LENGTH OF CUSTOMER DEFINED CALL/CALLI UUO'S
;(MINIMUM CALLI NUMBER, TOO)
;GENERATE DIGITAL UUO'S
DEFINE X (A,B,C) <
IFL .-UCLTAB-MAXCAL,<EXP SIXBIT /A/>
>
UCLTAB: NAMES
XP UCLLEN,.-UCLTAB ;DEFINE LENGTH OF DIGITAL UUO TABLE
DEFINE X (A,B,C)
< ZZ==ZZ+1
DEFINE XX (D) ;DEFINE XX IN CASE ODD NUMBER OF CUSTOMER UUO'S
< XWD CPOPJ##,D
>>
ZZ==0
;COUNT NUMBER OF CUSTOMER DEFINED UUO'S
CNAMES
;GENERATE HALF WORD UUO DISPATCH TABLE
DEFINE X (A,B,C)
< IFE ZZ&1,
< DEFINE XX (D)
<
XWD B,D
>>
IFN ZZ&1,
<
XX B
>
ZZ==ZZ+1
>
;GENERATE CUSTOMER TABLE
CUSTAB: CNAMES
ZZ==0
;GENERATE DIGITAL TABLE
UCLJMP: NAMES
IFN ZZ&1,<XX CPOPJ##> ;GEN. LAST WORD IF ODD NUMBER OF UUOS
UCILEN==:<.-UCLJMP>*2 ;MAX DIGITAL CALLI INDEX
IFN FTVM!FTMS,<
DEFINE X(A,B,C)
< ZZ==ZZ+1
>
DEFINE XX(D) ;DEFINE XX IN CASE ODD NO. OF CUST. CALLI'S
< XWD 0,D
>
ZZ==0
;COUNT NUMBER OF CUSTOMER CALLI'S
CNAMES
DEFINE X (A,B,C)
<IFE ZZ&1,
<DEFINE XX (D)
<
XWD C,D
>>
IFN ZZ&1,
<
XX C
>
ZZ==ZZ+1
>
CNAMES
ZZ==0
CHKTBC::NAMES
IFN ZZ&1,< XX 0>
>
SUBTTL EXIT & SETPOV UUO'S
;EXIT UUO ROUTINE
;CALL: CALL FIELD, [SIXBIT/EXIT/]
;IF FIELD - 0, PRINT EXIT ^C. CONT WILL NOT WORK
EXIT:
IFN FTLOGIN,<
MOVSI T1,JLOG
TDNN T1,JBTSTS##(J) ;IS THIS JOB LOGGED IN?
JRST LOGOUT ;NO, GO DESTROY JOB
>
JUMPN P1,MONRET ;AC FIELD NON-ZERO?
PUSHJ P,IORELS ;NO, RELEASE ALL DEVICES
PUSHJ P,RESET ;AFTER CLOSING OUT FILES, RELEASE RT DEV
;UNLOCK JOB, RESET APR
PUSHJ P,TTYFUW## ;FIND TTY FOR CURRENT JOB
; SET J TO JOB NO.,U TO OUTPUT BYTE POINTER
; F TO TTY DDB
JSP T1,PHOLD## ;MOVE "EXIT" TO OUTPUT BUFFER
; AND STOP JOB, AND START TTY, CONT WILL NOT WORK
ASCIZ /
EXIT/
; CALL 1,[SIXBIT/EXIT/] - RETURN TTY TO MONITOR MODE,
; STOP JOB, BUT DO NOT RELEASE DEVICES
;TYPE . WITH NO CRLF, ALLOW CONT COMMAND TO RETURN AFTER UUO
MONRET: PUSHJ P,TTYFUW## ;FIND TTY FOR CURRENT JOB
PUSHJ P,PRRSP3## ;PRINT [XXX], CRLF, DOT
PUSHJ P,TTYSTC## ;PUT TTY INTO COMMAND MODE
PUSHJ P,STOP1C## ;START TTY IN MONITOR MODE AND STOP JOB, BUT ALLOW
; CONTINUE TO WORK (RETURN CONTROL AFTER EXIT UUO)
JRST USCHED## ;CALL SCHEDULER WHICH WILL SET CURRENT JOB
; WITH RUN BIT OFF AND WILL STOP JOB
;SETPOV - SET PUSH DOWN OVERFLOW TRAP
;CALL MOVE AC,ADR. OF TRAP ON PD OVF
; CALL AC,[SIXBIT /SETPOV/]
SETPOV: MOVEM T1,JOBAPR##(R)
MOVEI T1,1B19
JRST APRENB ;SET TRAP LOC.
SUBTTL RESET & APRENB UUO'S
RESET::
IFN FTKL10,<
PUSHJ P,CPUCDB## ;P4=THIS CPUS CDB
PUSHJ P,HAVPMR## ;HAVE PERFORMANCE METER?
CAIA ;NO, DON'T GIVE IT UP
PUSHJ P,RELPMR## ;YES, GIVE IT BACK.
PUSHJ P,FEDRST## ;RELEASE FRONT END DEVICE
>;END IFN FTKL10
PUSHJ P,TTYRES## ;NORMALIZE CONTROLLING TTY, IF ANY
IFN FTHIBWAK,< ;HIBERNATE-WAKE FEATURE?
IFN FTHPQ,< ;HIGH PRIORITY QUEUE FEATURE?
LDB T2,HPQSPT## ;CONSOLE COMMAND HPQ SETTING
>
HRLOI T1,HPQMSK## ;MASK OUT LH BITS LEAVE RH SAME
; (REAL TIME DEVICE COUNT)
ANDM T1,JBTRTD##(J) ;CLEAR ALL BUT CONSOLE COMMAND HPQ
IFN FTHPQ,< ;HIGH PRIORITY QUEUE
DPB T2,HPQPNT## ;RESTORE CONSOLE COMMAND AS OPERATING QUEUE
> ;END FTHPQ
> ;END FTHIBWAK
IFN FTNET,<
;THIS CALL MUST PRECEED THE CALL TO UNLOCK BELOW
PUSHJ P,NETCTC## ;ALSO CALL NETSER ON CONTROL ^C
>;END FTNET
IFN FTLOCK,<
PUSHJ P,UNLOCK## ;TURN OFF NSHF AND NSWP AND RETURN CORE
>
IFN FTTRPSET,<
SETZM STOPTS## ;MAKE SURE SCHEDULING ALLOWED
; IN CASE THIS FOLLOWS A TRPSET UUO
;(IF STOPTS IS NON-ZERO, THIS MUST BE
; THE JOB THAT STOPPED TIME SHARING)
IFN FTMS,< CAMN J,.C1STS## ;IS THIS THE SLAVE JOB DOING A TRPSET
SETZM .C1STS## ;YES, CLEAR HIS STOP TIME SHARING FLAG
PUSHJ P,CRESET## ;RESET UUO SET CPU SPECIFICATION
>
>
IFN FT2REL,<
PUSHJ P,HRESET## ;FLAG USER AS HAVING UWP ON FOR HIGH SEG
; AND DO DATAO TO SET UWP ON
>
PUSHJ P,FNDPDS## ;FIND THE JOB PDB
HRRZ T2,.PDSCX##(W) ;ADDRESS OF JOB'S SAVED CONTEXT
MOVEI T1,NWSCTX ;NUMBER OF WORDS OF SAVED CONTEXT
SKIPE T2 ;HAS THE JOB'S CONTEXT BEEN SAVED?
PUSHJ P,GIVWDS## ;YES, RETURN SPACE TO MONITOR FREE CORE
HLLZS .PDSCX##(W) ;INDICATE NO SAVED CONTEXT
IFN FTSET,<
PUSHJ P,CLRBRK## ;CLEAR ADDRESS BREAK IF SET BY UUO
>
IFN FTPI,<
PUSHJ P,CLRPSI## ;RESET SOFTWARE INTERRUPT STATUS
>
IFN FTEQDQ,<
PUSHJ P,ENQRST## ;CLEAR ALL LOCKS
>
IFN FTIPCF,<
PUSHJ P,IPCFRS## ;SIGNAL RESET TO SYS:INFO
>
MOVEI T1,RELEA5 ;RELEASE ALL DEVICES
PUSHJ P,IOALL ; WITHOUT WAITING
IFN FTWATCH,<
HRRZS JBTPC##(J) ;NOT IN IOWAIT NOW (FOR ^T'ERS)
>
PUSHJ P,SETUSR ;CLEAR USERS JOB DATA AREA
IFE FTVM,<
SKIPE T2,USREPL## ;JOB HAVE EXTENDED PD LIST IN EXEC?
PUSHJ P,GIVEPL## ;YES. RETURN IT
> ;END IFE FTVM
MOVSI T1,777777-USRMOD ;CLEAR ALL UUO PC FLAGS IN LH, EXCEPT USER MODE
ANDCAM T1,JOBPD1##(R) ;LEAVE USER MODE OFF TOO, IF EXEC DOING CALL RESET
; FALL INTO APRENB WITH RH T1=0
; SO THAT ALL APR INTERRUPTS WILL BE DISABLED
;ROUTINE TO SET UP APR FOR USER TRAPPING
;CALL: CALL AC,[SIXBIT /APRENB/]
;WITH FOLLOWING APR CONSO FLAG BITS
;TO INDICATE WHICH APR CONDITIONS SHOULD
;TRAP TO USER WHEN TRAP OCCURS FROM USER MODE
;1B18 ;DO NOT DISABLE SELECTED CONDITIONS (EXCEPT CLOCK) SEE APRINT
;1B19 ;PUSHDOWN OVERFLOW
;1B22 ;ILLEGAL MEMORY
;1B23 ;NON-EXISTENT MEMORY
;1B26 ;CLOCK
;1B29 ;FLOATING POINT OVERFLOW
;1B32 ;ARITH. OVERFLOW
APRENB::
HRRM T1,JOBENB##(R) ;SET RH TO CONSO BITS IN JOB DATA AREA
; USED EVERY TIME IS STARTED UP
JRST SETAPR## ;GO ENABLE/DISABLE APR FOR FOV AND HR OV
; ALSO SET APR CONSO INSTR. FOR PROPER FLAGS
; AND RETURN TO USER
SUBTTL MISC. ACCOUNTING UUOS (JOBNO,JOBTIM,DATE & MSTIME)
;RETURN JOB NUMBER FOR THIS JOB
JOBNO: SKIPA T1,J ;JOB NUMBER
; SKIP AND STORE T1 IS USER AC
;RETURN THE DATE TO THE USER
DATE: MOVE T1,THSDAT##
JRST STOTAC##
;RETURN JOB RUNNING TIME IN MILLISECONDS
JOBTIM:IFN FTTIME,<
PUSHJ P,JOBTMM ;GET JOBS RUN TIME
PJRST STOTAC## ; AND STORE IT
;THIS CODE DEPENDS UPON RTUPS BEING AN INTEGRAL MULTIPLE OF ^D100000
JOBTMM::MOVEI T3,RTUPS3## ;ASSUME MILLISECOND RESOLUTION
TLZE T1,(1B0) ;IF SIGN BIT = 1
MOVEI T3,RTUPS5## ; RETURN 10 USEC. RESOLUTION
IMUL T3,TICSEC##
PUSH P,T3 ;SAVE FOR LATER DIV
PUSHJ P,LGLPR1## ;SKIP IF LEGAL JOB NUMBER (0 IS OK)
JRST JOBTM3
IFE FTPDBS,< ;IF PDBS ARE ALWAYS IN CORE THIS IS EASY
SKIPN T1
SKIPA T1,J
MOVE J,T1 ;J PROCESS # IN QUESTION
PUSHJ P,FNDPDB## ;FIND THE PDB
JRST JOBTM3 ;IF NONE RETURN ZERO
> ;END FTPDBS
IFN FTPDBS,< ;IF PDBS ARE ON THE DISK
MOVE T2,T1 ;T2 HOLDS THE PROCESS NUMBER
MOVE T3,PDIOWD## ;T3 IS THE IOWD
PUSHJ P,SCWAIT## ;GET THE SC RESOURCE
PUSHJ P,REDPDB## ;PUT THE PDB IN THE BUFFER
MOVEI W,PDBUFF## ;POINT TO PDB
> ;END FTPDBS
PUSHJ P,CPUJOB## ;SET UP J FROM JOB
IFN FTEMRT,<
MOVEI T1,ST%EMR ;EBOX MBOX ROUTINE?
TDNN T1,CNFST2## ;?
JRST JOBTM1 ;NO, COMPUTE RUNTIME NORMAL WAY
;YES,
.MOVE T1,.PDMB2##(W) ;GET REMAINDER FROM MBOX JIFFY CALCULATION
MULI T1,RTUPS## ;COMPUTE LEFTOVER*RTUPS/MBOX TICKS PER JIFFY
DIV T1,.CPMBJ##(P4) ;LEAVE IN T1
.MOVE T3,.PDEB2##(W) ;SAME FOR EBOX TICKS
MULI T3,RTUPS
DIV T3,.CPEBJ##(P4)
ADD T3,T1 ;RESULT CANNOT BE GREATER THAN 2*RTUPS,
; WHICH FITS IN 36 BITS
.MOVE T1,.PDEBT##(W) ;GET EBOX TICKS
.ADD T1,.PDMBT##(W) ;COMPUTE EBOX/MBOX HIGH ORDER RUNTIME
MULI T1,RTUPS## ;CONVERT TO HIGH PRECISION UNITS
ADD T2,T3 ;ADD LOW ORDER PART FROM T3
JRST JOBTM2 ;GO JOIN COMMON CODE AGAIN
JOBTM1:>;END FTEMRT
.MOVE T1,.PDTTM##(W) ;TOTAL JOB RUNNING TIME
MULI T1,RTUPS## ;EXPAND TO FULL PRECISION
.ADD T2,.PDTT2##(W) ;ADD JIFFY FRACTION
JOBTM2: TLZE T2,(1B0) ; DOUBLE PRECISION
AOS T1
POP P,T3
DIV T1,T3
IFN FTPDBS,< ;IF WE GOT THE SC RESOURCE ABOVE
PUSHJ P,SCFREE## ;RETURN THE RESOURCE
> ;END FTPDBS
POPJ P,
JOBTM3: SETZM (P) ;RETURN ZERO
JRST TPOPJ##
>
IFE FTTIME,<
JRST RTZER ;RETURN ZERO IF NO TIMMING COM.
>
;RETURN TIME OF DAY IN MILLISECONDS
MSTIME: MOVE T1,TIME## ;USE APR CLOCK BECAUSE IT HAS BETTER LONG
; TERM ACCURACY
IMULI T1,^D1000 ;CONVERT TO MILLISECONDS
IDIV T1,TICSEC##
JRST STOTAC##
SUBTTL SLEEP SERVICE FOR SLEEP UUO, DTA, MTA AND SCNSER.
;PUT JOB TO SLEEP FOR NSECONDS
;CALL CALL AC,[SIXBIT /SLEEP/]
;AC=XWD LOC,N N=NUMBER OF SECONDS TO SLEEP
;IF LH(AC)NON-0, SLEEP ONLY IF LOC THROUGH LOG+17
; MATCHES THE CURRENT JOBSTS ON THAT CHAN, OR IS 0
SLEEP::
IFN FTSLEEP,<
SETZ F, ;LET WORLD KNOW THIS IS NOT AN I/O UUO
IMUL T1,TICSEC## ;CONVERT TO TICKS
ANDI T1,7777
MSLEEP: TRNN T1,7777 ;0 TIME?(CHECK ONLY 12 BITS)
MOVEI T1,1 ;YES. SLEEP 1 JIFFY
IFN FTSWAP,<
PUSH P,W ;SAVE W FOR DTASRN WHERE IT POINTS
; TO CONTROLER DATA BLOCK
PUSHJ P,FNPDBS## ;FIND THE PDB OR STOP
.LDB T2,PDYIPT## ;GET PROTECT TIME
CAIGE T2,(T1) ;SLEEPING LONGER THAN PROTECT TIME?
PUSHJ P,CLRIPT## ;YES. CLEAR PROTECT TIME
POP P,W
>
PUSH P,T1 ;SAVE SLEEP TIME
HRLI T1,WAKEJ## ;ADR. IN RUNCSS WHEN JOB WAKES UP
MOVEI T2,CLKR
TDNE T2,JBTSTS##(J) ;DOES THIS JOB HAVE A CLOCK QUEUE
; REQUEST IN CLOCK QUEUE?
JRST XSLEEP ;YES, DO NOT PUT ANOTHER ONE IN
SSLEEP: CONO PI,PIOFF##
IDPB T1,CLOCK##
IDPB J,CLOCK##
CONO PI,PION##
JRST SLPNAP ;SET JOB STATUS WORD SO JOB WILL NOT RUN
XSLEEP: MOVE T2,T1 ;TIME TO SLEEP
MOVE T1,J ;JOB NUMBER
PUSHJ P,CLKCHG## ;FIX UP THE CLOCK REQUEST
JRST SSLEEP ;NO, ENTRY FOUND IN THE CLOCK QUEUE
; SO MAKE ONE NOW
SLPNAP: POP P,T1 ;RESTORE SLEEP TIME
PUSHJ P,SAVE4## ;SETSLP USES 16,17
MOVEI T2,JIFSEC## ;GET SECONDS WORTH OF JIFFIES
CAIL T2,(T1) ;SLEEPING LONGER THAN A SECOND?
JRST SETNAP## ;NO, JUST GIVE THIS JOB A NAP
JRST SETSLP## ;YES, PUT THIS JOB TO SLEEP
>;END IFN FTSLEEP
IFE FTSLEEP,< POPJ P, ;RETURN IMMEDIATELY IF NOT A FEATURE>
SUBTTL PEEK UUO
;PEEK INTO MONITOR UUO
;CALL MOVEI AC,<MONITOR ADDRESS>
; CALL AC,[SIXBIT .PEEK.]
IFN FTPEEKSPY,< ;PEEK AND SPY
UPEEK: JUMPL T1,RTZER ;RETURN 0 IF NEGATIVE ARGUMENT
MOVE T2,T1 ;SAVE ARG
IFE FTPRV,<
IFN FTLOGIN,<
HLRZ T1,JBTPPN##(J) ;GET USER'S PROJECT NUMBER
CAIN T1,1 ;SKIP IF SYSTEM ADMINISTRATOR
;DON'T ALLOW REGULAR USERS TO DO THIS
; NOTE PATCH TO JFCL IF OK
>
CAMLE T2,SYSSIZ## ;SKIP IF ASKING FOR LEGAL VALUE
>
IFN FTPRV,< MOVSI T1,PVSPYA ;SEE IF USER MAY SPY ON ALL CORE
PUSHJ P,PRVBIT## ;..
JRST PEEKOK ;YES. OK
MOVSI T1,PVSPYM ;NO. MAY HE SPY ON MONITOR?
PUSHJ P,PRVBIT## ;..
JRST PEEK1 ;YES
JRST RTZER ;NO. ERROR, RETURN 0.
PEEK1: CAMGE T2,SYSSIZ## ;IS HE ASKING FOR LEGAL VALUE?
PEEKOK:
CAML T2,MEMSIZ## ;..
>
JRST PEEKHI ;NO. FAILURE. RETURN 0
GOPEEK: MOVE T1,0(T2) ;YES. GET WORD
JRST STOTAC## ;RETURN IT TO USER IN AC.
IFN FT2SEGMON,<
PEEKHI: MOVE T3,SYSLEN## ;SIZE OF HISEG
CAIL T2,MONORG ;IS THIS IN THE
CAILE T2,MONORG(T3) ; HISEG
JRST RTZER ; NO
JRST GOPEEK ; YES
> ;END FT2SEGMON
> ;END IFN FTPEEKSPY
SUBTTL POKE. UUO
;POKE. -- PRIVILEGED UUO TO ALTER THE MONITOR
;CALL: MOVE AC,[3,,BLOCK]
; POKE. AC,
; ERROR
; OK
;ERROR RETURN WITH AC UNCHANGED IF NOT IMPLEMENTED
; AC=0 IF NOT PRIVILEGED
; AC=1 IF BAD MATCH
; AC=2 IF BAD ADDRESS
;
;BLOCK: LOCATION
; +1 OLD VALUE
; +2 NEW VALUE
IFN FTPOKE,<
POKE: PUSHJ P,SAVE2## ;SAVE P1-P2
MOVE P1,T1 ;SAVE ARGUMENT
MOVSI T1,JP.POK ;CHECK FOR POKE
PUSHJ P,PRVBIT## ; PRIVILEGES
CAIA
JRST RTZER ;NO--BOMB USER
HRR M,P1 ;POINT TO BLOCK
PUSHJ P,GETWDU## ;GET LOCATION
IFN FT2SEGMON,<
MOVE T2,SYSLEN##
CAIL T1,MONORG
CAILE T1,MONORG(T2)
CAIA
JRST POKE0>
CAILE T1,17 ;CHECK ADDRESS
CAML T1,MEMSIZ## ; SEE IF LEGAL
PJRST ECOD2## ;NO--BOMB USER WITH ERROR 2
POKE0: MOVE P1,T1 ;SAVE ADDRESS
MOVE P2,T1
PUSHJ P,GETWD1## ;GET USER'S IDEA OF
; OLD CONTENTS
MOVE T4,T1 ;SAVE IT
PUSHJ P,GETWD1## ;GET NEW VALUE
IFN FT2SEGMON,<
MOVE T2,SYSLEN##
CAIL P1,MONORG
CAILE P1,MONORG(T2)
JRST POKE1
MOVE T2,P1
LSHC T2,W2PLSH##-1
TLNN T3,400000
TDOA T2,[POINT 18,.EPPM##,17]
TDO T2,[POINT 18,.EPPM##,35]
LDB T2,T2
TRO T2,PM.WRT
HRRM T2,.UPMP+.MTEMP
MOVEI T2,.TEMP/1000
DPB T2,[POINT 9,P1,26]
CLRPGT (0,.TEMP)
>
POKE1: CONO PI,PIOFF## ;TO BE SAFE
CAME T4,(P1) ;COMPARE OLD VALUE
JRST POKE.1 ;FAIL--BOMB USER
MOVEM T1,(P1) ;WIN--STORE
CONO PI,PION## ;TURN ON SYSTEM
AOS LASPUC## ;INCREMENT COUNT OF NO. OF POKE UUOS
HRLM J,LASPUC## ;ALSO STORE JOB NO WHICH POKED LAST
MOVEM P2,LASPOK## ;SAVE LOCATION CHANGED TOO (LEAVE ROOM FOR 22 BIT ADR)
; USEFUL IN CASE OF CRASH CAUSED BY POKE
JRST CPOPJ1## ;SKIP RETURN
POKE.1: CONO PI,PION## ;TURN ON SYSTEM
PJRST ECOD1## ;RETURN CODE 1
>
IFE FTPOKE,<POKE==CPOPJ##>
SUBTTL PERF. MUUO
;THE PERF. MUUO IS INTENDED TO BE A GENERAL PURPOSE CALL
; TO EXECUTE SYSTEM PERFORMANCE MEASURING FUNCTIONS. THESE FUNCTIONS
; INCLUDE HANDLING OF THE KL10 PERFORMANCE METER. THE METER IS
; CONSIDERED A RESOURCE WHICH CAN BE USED ONLY BY ONE PROCESS AT A TIME.
;
;CALL TO THE PERF. MUUO:
;
; MOVE AC,[XWD N,ADDR] ;COUNT OF FUNCTIONS, ADDRESS
; PERF. AC, ;OR CALLI AC,***
; <ERROR RETURN> ;ERROR CODE RETURNED IN AC
; <SUCCESSFUL RETURN>
;
;ADDR: XWD FUNCTION,BLOCK
; XWD FUNCTION,BLOCK
; .
; .
; . ;N FUNCTIONS
;
;THE LOCATION BLOCK ALWAYS CONTAINS COUNT OF THE NUMBER OF
; WORDS FOLLOWING IN THE BLOCK. THE REST OF THE
; BLOCK IS FUNCTION SPECIFIC.
;
;THE MAIN LOOP OF THE PERF. UUO IS RESPONSIBLE FOR SETTING UP
; P2 FROM THE ITEM COUNT AT LOCATION BLOCK, CHECKING AND DISPATCHING
; FROM THE FUNCTION NUMBERS PROVIDED, AND SETTING UP THE RIGHT HALF
; OF AC M TO POINT TO BLOCK OF THE CURRENT FUNCTION IT IS EXECUTING.
; IT EXPECTS P1 TO BE PRESERVED BY THE FUNCTION EXECUTION ROUTINES, SINCE
; P1 IS USED AS AN AOBJN POINTER TO THE LIST OF FUNCTIONS TO BE EXECUTED.
;
;THE FUNCTION EXECUTION ROUTINES USE ACS T1-T4, AND A SPECIAL ARGUMENT
; GETTER THAT THEY CALL USES P2 TO DETERMINE IF THE ARGUMENTS IN BLOCK
; ARE EXHAUSTED OR NOT. THE ROUTINES THAT HANDLE THE KL10 PERFORMANCE
; METER TAKE ADVANTAGE OF THE FACT THAT ZERO IS ALWAYS DONT CARE BY
; SIMPLY RETURNING ZERO IF THE ARGUMENT IS NOT PRESENT.
;INTERN THE ERROR RETURNS SO THE MODULES CAN CALL THEM
INTERN PREICT,PRENXC,PREIPM,PREMNS,PREMIU,PREMAS,PREBJN
INTERN PREMNR,PREFNI,PREBFN,PREMBP
UPERF.::PUSHJ P,SAVE2## ;P1 AND P2 WILL BE USED
MOVE P1,T1 ;SAVE C(AC)
PUSHJ P,PRVJ ;PRIVS?
CAIA ;YES
JRST PREMBP ;**MUST BE PRIVILEGED**
HLRE T1,P1 ;GET POSITIVE COUNT IN T1
JUMPLE T1,CPOPJ1## ;FINISHED IF .LE. ZERO
MOVNS T1 ;MAKE AOBJN POINTER
HRL P1,T1 ;PUT -COUNT IN LH OF P1, AOBJN POINTER
UPERF1: HRR M,P1 ;GET NEXT FUNCTION
PUSHJ P,GETWDU## ;GET FUNCTION,,BLOCK
HRR M,T1 ;PUT ADDRESS OF BLOCK IN M
HLRZ T4,T1 ;SAVE FUNCTION NUMBER IN T4
CAILE T4,PRFMAX ;IS THE FUNCTION DEFINED?
JRST PREFNI ;NO, GIVE HIM UNIMPLEMENTED ERROR
PUSHJ P,GETWDU## ;GET COUNT OF ITEMS IN BLOCK
;M NOW POINTS TO BLOCK FOR FUNCTION ROUTINE
MOVE P2,T1 ;SAVE COUNT IN P2 WHERE IT BELONGS
ROT T4,-1 ;TAKE INTO ACCOUNT DISPATCH TABLE IS 1/2 WORDS
MOVE T3,UPRFDS(T4) ;GET ENTRY
SKIPL T4 ;SKIP IF ITS THE ODD ENTRY
MOVSS T3 ;NOT, ITS THE EVEN
PUSHJ P,(T3) ;DISPATCH TO PROPER ROUTINE
POPJ P, ;ROUTINE GAVE ERROR RETURN, STOP UUO
AOBJN P1,UPERF1 ;OK SO FAR, DO MORE FUNCTIONS IF ANY LEFT
JRST CPOPJ1## ;EVERYTHING IS BEAUTIFUL (IN ITS OWN WAY)
;DISPATCH TABLE
; HERE WE MUST EITHER EXTERN THE ADDRESS OF THE FUNCTION ROUTINE,
; OR DEFINE THE FUNCTION TO JUMP TO THE ERROR ROUTINE
; THAT INDICATES UNIMPLEMENTED FUNCTION.
IFN FTKL10,<
EXTERN CPOPJ,PMRSET,PMRSTR,PMRRED,PMRSTP,PMRREL
>;END IFN FTKL10
IFE FTKL10,<
PMRSET==PREFNI
PMRSTR==PREFNI
PMRRED==PREFNI
PMRSTP==PREFNI
PMRREL==PREFNI
>;END IFN FTKL10
UPRFDS: XWD CPOPJ##,PMRSET ;(0,1)
XWD PMRSTR,PMRRED ;(2,3)
XWD PMRSTP,PMRREL ;(4,5)
PRFMAX==<.-UPRFDS>*2-1 ;MAXIMUM FUNCTION NUMBER
;NOTE THAT IF LAST WORD IN DISPATCH
;TABLE HAS ONLY ONE FUNCTION,
;THE OTHER SLOT MUST HAVE PREFNI IN IT.
;ERROR RETURNS - USE SYSTEM ERCODE MACRO
PRFBC%==1
PRFNC%==2
PRFIM%==3
PRFNS%==4
PRFMB%==5
PRFAS%==6
PRFBJ%==7
PRFMS%==10
PRFUF%==11
PRFBF%==12
PRFNP%==13
ERCODE PREICT,PRFBC% ;IMPROPER CPU TYPE
ERCODE PRENXC,PRFNC% ;NON-EXISTANT CPU
ERCODE PREIPM,PRFIM% ;IMPROPER MODE
ERCODE PREMNS,PRFNS% ;METER NOT SETUP
ERCODE PREMIU,PRFMB% ;METER BUSY
ERCODE PREMAS,PRFAS% ;METER ALREADY STARTED
ERCODE PREBJN,PRFBJ% ;BAD JOB NUMBER
ERCODE PREMNR,PRFMS% ;METER NOT RUNNING
ERCODE PREFNI,PRFUF% ;UNIMPLEMENTED FUNCTION
ERCODE PREBFN,PRFBF% ;BAD FUNCTION NUMBER
ERCODE PREMBP,PRFNP% ;NO PRIVILEGES
SUBTTL CALLS TO SEGCON FOR SETUWP AND REMAP
;SET OR CLEAR USER MODE WRITE PROTECT BIT IN HIGH SEG FOR THIS USER ONLY
;CALL: MOVEI AC,0 OR 1
; CALL AC,[SIXBIT /SETUWP/] OR CALLI AC,34
; ERROR - MACHINE OR MONITOR CANNOT HANDLE TWO REG, OR TRYING TO CLEAR
; ;UWP OF A SHARABLE SEG(AC=1 ON RETURN)
; OK RETURN - AC CONTAINS PREVIOUS SETTING( OR JOB HAS NO HIGH SEG)
IFN FT2REL,<
SETUWP=USTUWP## ;GO TO ROUTINE IN SEGCON
;IF FT2REL=0, SETUWP DOES RTZER
>
;UUO TO REMAP TOP PART OF LOW SEGMENT INTO HIGH SEGMENT
;PREVIOUS HIGH SEG(IF ANY) IS KILLED AND A NEW SEGMENT NUMBER IS ASSIGNED
;TO THIS JOB. REMAP IS USED BY LOADER AND GET
;CALL: MOVEI AC,NEW HIGHEST USER ADR IN LOW SEG(EXEC ORS IN 1777)
; CALL AC,[SIXBIT /REMAP/] OR CALLI AC,35
; ERROR RETURN, MACHINE OR EXEC CANNOT HANDLE 2 REG OR DESIRED ADR
; ;GREATER THAN OLD LOW SEG
; OK RETURN, LOW SEG ABOVE ARG NOW THE HIGH SEG
IFN FT2REL,<
REMAP=UREMAP## ;CORE1 MODULE IN SEGCON
>
IFE FT2REL,<
REMAP=CPOPJ## ;ERROR RETURN TO USER(CPOPJ IS AN EXTERN)
>
SUBTTL TRIVIAL UUOS (LIGHTS, TIMER AND SWITCH)
;SET LIGHTS ON CONSOLE FROM USER PROGRAM
;CALL AC,[SIXBIT /DATAO/] OR CALLI AC,-1
;THIS IS AN EXAMPLE OF A USER DEFINED UUO WITH A NEGATIVE CALLI ARG.
LIGHTS:
IFN FTKI10!FTKA10,<
DATAO PI,T1 ;SENT USER'S AC TO CONSOLE LIGHTS
>;END IFN FTKA10!FTKI10
POPJ P, ;RETURN TO HIM
;RETURN TIME OF DAY IN JIFFIES (60THS,50THS OR MS)
TIMER: SKIPA T1,TIME## ;FALL INTO STOTAC
;RETURN DATA SWITCHES
SWITCH:
IFN FTKA10!FTKI10,<
DATAI APR,T1 ;GET 36 BIT SWITCHES
>
IFN FTKL10,<
SETZ T1, ;RETURN ZERO ON KL10
>
JRST STOTAC## ;GO STORE VALUE
IFN FT5UUO,<
SUBTTL DVPHY. UUO
;THE DVPHY. UUO RETURNS THE PHYSICAL NAMES OF ALL THE DEVICES OF A
; CERTAIN TYPE OR OPTIONALLY, THE PHYSICAL NAMES OF ALL THE DEVICES
; ON THE SYSTEM (EXCLUDING PTYS, TTYS, MPXS, AND DSK).
;CALLING SEQUENCE:
; MOVE AC,[N,,ADDR] ;COUNT,,ARGUMENT
; DVPHY. AC, ;OR CALLI AC,164
; <ERROR RETURN>
; <NORMAL RETURN>
;
;WHERE
;ADDR: DEVICE TYPE OR -1 IF ALL DEVICES
;+1 0 FOR FIRST CALL, PREVIOUS DEVICE NAME ON SUBSEQUENT CALLS
;NEXT PHYSICAL DEVICE NAME IS RETURNED IN ADDR+1 OR 0 IF LAST
; DEVICE IN THE SYSTEM OF THAT TYPE.
DVPHY.: PUSHJ P,SAVE1## ;SAVE P1
HRR M,T1 ;ADR OF ARG BLOCK
HLRE T1,T1 ;LENGTH OF BLOCK
MOVMS T1 ;MAKE SURE IT'S POSITIVE
CAIGE T1,2 ;ENOUGH ARGS?
JRST DPEIAL ;INVALID ARG LIST
PUSHJ P,GETWDU## ;GET DEVICE TYPE
CAILE T1,TYPMAX ;LEGAL?
JRST DPENDT ;NO SUCH DEVICE TYPE
CAME T1,[-1] ;WANT EVERYTHING?
JUMPL T1,DPENDT ;NO, NO DEVICE IF NEGATIVE
MOVE P1,T1 ;SAVE ARGUMENT
PUSHJ P,GETWD1## ;GET NEXT ARG
JUMPGE P1,DVPHY2 ;GO IF DONT WANT EVERYTHING
HLRZ F,DEVLST## ;ALL, START AT START OF DEVS
JUMPE T1,DVPHY1 ;GO IF FIRST CALL
PUSHJ P,DEVPHY ;NOT FIRST, FIND THIS DEVICE
JRST DPENPD ;NOT THERE
HLRZ F,DEVSER(F) ;POINT AT NEXT DEVICE ON CHAIN
DVPHY1: PUSHJ P,NOTPTD ;FIND NEXT DEVICE
JRST DVPHY4 ;NO MORE, RETURN A ZERO
JRST DVPHY6 ;WON, STORE T1 AND SKIP RETURN
DVPHY2: JUMPN T1,DVPHY3 ;GO IF NOT 1ST CALL
MOVE T1,P1 ;AND HERE I GOT CONFUSED
PUSHJ P,DVSDVT
JRST DPENDT
JRST DVPHY5
DVPHY3: PUSHJ P,DEVPHY
JRST DPENPD
HLRZ F,DEVSER(F)
LDB T1,PDVTYP##
CAIE T1,.TYDSK/.TYEST
CAME T1,P1
DVPHY4: TDZA T1,T1
DVPHY5: MOVE T1,DEVNAM(F)
DVPHY6: AOS (P)
PJRST PUTWDU##
;SUBROUTINE TO SEARCH FOR A DEVICE TYPE
;CALLING SEQUENCE:
; MOVEI T1,DEVICE TYPE
; PUSHJ P,DVSDVT
;RETURNS CPOPJ IF NOT FOUND. CPOPJ1 IF FOUND, F POINTS AT THE FIRST
; DDB IN THE DEVICE CHAIN WHICH IS THAT DEVICE TYPE,
DVSDVT: HLRZ F,DEVLST##
DVSDV1: LDB T2,PDVTYP##
CAMN T1,T2
JRST CPOPJ1##
HLRZ F,DEVSER(F)
JUMPE F,CPOPJ##
JRST DVSDV1
;SUBROUTINE TO SEARCH FOR THE NEXT DEVICE WHICH IS NOT A PTY, TTY,
; OR DSK.
;CALLING SEQUENCE:
; MOVE F,PLACE TO START ON THE DDB CHAIN
; PUSHJ P,NOTPTD
;RETURNS CPOPJ IF NO MORE DEVICES, CPOPJ1 WITH F POINTING AT THE
; DDB IF A DEVICE WHICH IS NOT A PTY, TTY, OR DSK IS FOUND, T1= DEVICE
; NAME.
NOTPTD: JUMPE F,CPOPJ##
MOVEI T1,NOTTTL
LDB T2,PDVTYP##
NOTPT1: CAIE T2,@NOTTBL-1(T1)
SOJG T1,NOTPT1
JUMPLE T1,NOTPT3
NOTPT2: HLRZ F,DEVSER(F)
JRST NOTPTD
NOTPT3: SKIPE T1,DEVNAM(F)
JRST CPOPJ1##
JRST NOTPT2
NOTTBL: XWD ZERO5,.TYPTY/.TYEST
XWD ZERO5,.TYTTY/.TYEST
XWD ZERO5,.TYDSK/.TYEST
XWD ZERO5,.TYMPX/.TYEST
XWD ZERO5,TYPMAX+1
NOTTTL==.-NOTTBL
;DVPHY. ERROR CODES
DVPIA%==1 ;INVALID ARGUMENT LIST
DVPIT%==2 ;INVALID DEVICE TYPE
DVPNP%==3 ;NO SUCH PHYSICAL DEVICE
DVPNT%==4 ;NO SUCH DEVICE TYPE
ERCODE DPEIAL,DVPIA% ;INVALID ARGUMENT LIST
ERCODE DPEIDT,DVPIT% ;INVALID DEVICE TYPE
ERCODE DPENPD,DVPNP% ;NO SUCH PHYSICAL DEVICE
ERCODE DPENDT,DVPNT% ;NO SUCH DEVICE TYPE
> ;END OF IFN FT5UUO
SUBTTL DEVCHR AND DEVSIZ UUO'S
;RETURN DEVICE CHARACTERISTICS
IFN FTSPL, <
DVCH0:
IFN FTPHYO,<
TLOE P1,PHONLY ;ALREADY HAVE REAL DEVICE ?
JRST DVCH1 ;YES, GET DEVMOD
>
MOVE T1,DEVNAM(F) ;NO, GET NAME USER SUPPLIED
HRRZ P2,DEVMOD(F) ;DEVMOD FOR SPOOLED DEVICE
TRZ P2,-1-<ASSCON!ASSPRG> ;SAVE ASSCON AND ASSPRG
JRST DVCH3 ;SKIP OVER SAVE AND CLEARING P2
DVCHR: PUSHJ P,SAVE2## ;SAVE P1-P2
SETZ P2, ;FIRST CALL - ZERO P2
DVCH3:
>
IFE FTSPL, <
DVCHR:
>
IFE FT5UUO,<
PUSHJ P,DEVSRC ;SEARCH FOR DEVICE
>
IFN FT5UUO,<
PUSHJ P,DVCNSG ;SEARCH FOR DEVICE
>
JRST RTZER ;NOT A DEVICE, RETURN ZERO
IFN FTNUL,<
SETZ T3,
CAMN T1,[SIXBIT /NUL/] ;NUL DEVICE?
MOVEI T3,-1-TTYATC ;YES, LH WILL BE CHANGED
>
IFN FTSPL, <
SKIPE DEVCHR(F) ;IF NOT A FAKE DDB,
SKIPL DEVSPL(F) ;IF A SPOOLED DEVICE,
DVCH1: SKIPA T1,DEVMOD(F)
JRST DVCH0 ; GO GET DEVMOD FOR REAL DEVICE
>
IFE FTSPL,<
DVCH1: MOVE T1,DEVMOD(F) ;REAL DEVICE FOUND, RETURN DEVMOD
>
IFN FTSPL,<
PUSHJ P,CHKSPL ;DEVICE SPOOLED?
TRZA T1,ASSCON!ASSPRG ;YES, IGNORE WHAT REAL DEV IS DOING
JRST DVCH2 ;NO
IOR T1,P2 ; AND SET ASSCON, ASSPRG FROM SPOOLED DDB
TLO T1,DVAVAL ;YES, SET AVAILABLE-BIT
DVCH2:
>
LDB T2,PJOBN## ;GET JOB NO. USING DEVICE
CAME T2,JOB## ;DOES CURRENT USER ALREADY HAVE IT?
TRNN T1,ASSCON+ASSPRG ;NO, IS IT ASSIGNED?
TLO T1,DVAVAL ;NO, BUT HE CAN GET IT.
IFN FTNUL,<
TLO T1,(T3) ;SET LH = -1 IF NUL:
>
PUSHJ P,TTYKLQ## ;DISCARD TTY DDB IF NOT IN USE
JRST STOTAC##
;SUBROUTINE TO DETERMINE IF CHARACTERISTICS OF DDB IN F SHOULD BE
; REPLACED BY THOSE OF THE SPOOLED DEVICE.
;CALL IS
; MOVE F,DDB-ADR
; PUSHJ P,CHKSPL
; SPOOLED RETURN
; NOT SPOOLED RETURN
;SPOOLED BIT FOR DEVICE (DEYSPL) RETURNED IN T2; OTHER ACS PRESERVED
IFN FTSPL,< ;IF SPOOLING
CHKSPL: LDB T2,DEYSPL## ;GET SPOOL BIT FOR DEVICE
SKIPN DEVCHR(F) ; "FAKE" (TABLE) DDB?
POPJ P, ;YES
TDNN T2,JBTSPL##(J) ;NO. JOB SPOOLING DEVICE?
JRST CPOPJ1## ;NO
PUSH P,T1 ;MAYBE. SAVE T1
PUSH P,T2 ; AND T2
MOVE T1,DEVMOD(F) ;GET DEVMOD
LDB T2,PJOBN## ;AND JOB OWNING DEVICE
TRNE T1,ASSCON!ASSPRG ;DEVICE ASSIGNED OR INITED?
CAME T2,JOB## ;YES, TO US?
SOS -2(P) ;NO, SPOOLED RETURN
POP P,T2 ;RESTORE T2
JRST TPOPJ1## ;RESTORE T1 AND EXIT SKIP/NO-SKIP
> ;END FTSPL
IFN FT5UUO,<
;RETURN DEVICE TYPE (AND OTHER PROPERTIES)
DVTYP: AOS (P) ;SKIP-RETURN SINCE UUO IS IMPLIEMENTED
PUSHJ P,DVCHR ;GET DEVICE CHARACTERISTICS
JUMPE T1,CPOPJ## ;NO SUCH DEV - RETURN 0
IFN FTSPL,<
PUSHJ P,CHKSPL ;SEE IF DEVICE IS SPOOLED
TLOA T2,.TYSPL!DVAVAL ;YES, SPOOL+AVAILABLE
> ;END CONDITIONAL ON FTSPL
DVTY1: SETZ T2, ;NO
MOVE T3,T2 ;SAVE DEVCHR WORD
TLZ T1,-1-DVIN-DVOUT-DVTTY-DVAVAL;SAVE CERTAIN BITS
OR T1,T2 ;+SPOOL+AVAILABLE
LDB T2,DEYTYP## ;GET TYPE+VAR BUFFER SIZE
IFN FTSPL,<
SKIPN DEVCHR(F) ;FROM TABLE?
HLRZ T2,SPLBIT##(F) ;YES, GET TYPE-NUMBER
>
TRZE T2,DERLEN ;VARIABLE BUFFER SIZE?
TLNE T1,.TYSPL ;YES, BEING SPOOLED?
JRST .+2 ;YES
TLO T1,.TYVAR ;UNSPOOLED, VARIABLE DEV
HRR T1,T2 ;GET TYPE INTO T1
IFN FTNUL,<
SKIPN T2 ;IF A DISK,
JUMPL T3,DVTY2 ; IF "DVDIRIN" IS ON ITS NUL:
>
IFN FTTSK!FTRDX,<
CAIE T2,.TYRDA/.TYEST ;IS IT A RDA
CAIN T2,.TYTSK/.TYEST ;IS IT A TASK
TLOA T1,.TYINT ;YES, SET INTERACTIVE MODE
>
CAIG T2,.TYDTA/.TYEST ;DSK OR DTA?
TLO T1,.TYMAN ;YES - LOOKUP/ENTER MANDATORY
DVTY2: LDB T2,PJOBN## ;OWNER OF DEVICE
IFN FTSPL,<
SKIPE DEVCHR(F) ;NO OWNER IF SPOOLED
>
DPB T2,[POINT 9,T1,26] ;IN BITS 18-26
IFN FTMSGSER,<
TLO T1,TY.MPX ;ASSUME OK
PUSHJ P,LGLMPX## ;IS IT OK?
TLZ T1,TY.MPX ;NO--CLEAR BIT
>
SKIPGE DEVCHR(F) ;IS THIS A LOWER CASE LPT?
TLO T1,TY.LL ;YES
MOVSI T2,DVCMDA ;IS THIS AN
TDNE T2,DEVCHR(F) ;MDA DEVICE?
TLO T1,TY.MDA ;YES
PJRST STOTAC## ;RETURN TO USER
;STILL IN FT5UUO CONDITIONAL
;RETURN BUFFER SIZE, STANDARD NO OF BUFFERS
;CALL: MOVE AC,LOC OF (2 WORRD) OPEN BLOCK
;CALLI AC,DVSIZ
;NOT IMPLEMENTED RETURN
;AC=XWD NO OF BUFS,BUF SIZE
DVSIZ: PUSHJ P,SAVE1## ;SAVE P1
PUSH P,M ;SAVE M
HRR M,T1 ;GET LOC OF OPEN-BLOCK
PUSHJ P,GETWDU## ;GET MODE
MOVE P1,T1 ;SAVE IT
PUSHJ P,GETWD1## ;GET DEVICE
PUSHJ P,DVCNSG ;FIND ITS DDB
TDZA T1,T1 ;NOT A DEVICE
SKIPA M,P1 ;FOUND - SET M=MODE
SOJA T1,SIZRET ;NOT A DEV - RETURN AC=-1
MOVEI T2,1 ;SET FOR MODE TEST
ANDI P1,17 ;GET MODE ALONE
LSH T2,(P1) ;POSITION THE BIT
SETZI T1, ;IF MODE IS ILLEGAL,
CAIL P1,SD ;TEST FOR DUMP MODE
JRST SIZRT1 ;IT IS, RETURN AC=0
MOVNI T1,2
TDNN T2,DEVMOD(F) ; RETURN AC=-2
PJRST SIZRET
IFN FTSPL,<
PUSHJ P,CHKSPL ;SPOOLED DEVICE?
MOVEI F,DSKDDB## ;YES, SET FOR A DISK
> ;END CONDITIONAL ON FTSPL
MOVE T4,DEVSER(F) ;LOC OF DISPATCH TABLE
PUSHJ P,DSZ(T4) ;GET BUFFER SIZE
PUSHJ P,DFTNB ;FIND DEFAULT NUMBER OF BUFS
HRL T1,T2 ;RETURN IN LH(T1)
ADDI T1,2 ;BUMP SIZE BY 2 HOUSEKEEPING WORDS
SIZRT1: AOS -1(P) ;GIVE SKIP RETURN
SIZRET: POP P,M ;RESTORE LOC OF AC
PJRST STOTAC## ;STOTAC, THEN SKIP-RETURN
> ;END CONDITIONAL ON FT5UUO
IFE FT5UUO,<
DVTYP==CPOPJ##
DVSIZ==CPOPJ##
>
;SUBROUTINE TO SET T1=LENGTH OF A NON-VARIABLE BUFFER
REGSIZ::LDB T1,PBUFSZ## ;NORMAL SIZE
POPJ P, ;RETURN
;DEVGEN -- RETURN RANGE AND STATION OF GENERIC DEVICES
;CALL: MOVE AC,SIXBIT NAME OF DEVICE
; CALLI AC,DEVGEN
;RETURNS CPOPJ IF UNIMPLEMENTED OR IF NO SUCH DEVICE (AC UNCHANGED)
;RETURNS CPOPJ1 IF DEVICE FOUND WITH AC AS FOLLOWS:
; BITS 0-8: LOWEST DEVICE NUMBER MATCHING GENERIC NAME
; 9-17: HIGHEST DEVICE NUMBER MATCHING
; 18-35: STATION NUMBER OF DEVICE
;IN PARTICULAR, DEPENDING ON THE TYPE OF NAME SPECIFIED, THE
;FOLLOWING RESULTS:
; (1) SPECIFIC (E.G. LPT153)
; LOW=HIGH=UNIT NUMBER (153)
; (2) STATION GENERIC (E.G. LPTS3)
; LOW=LOWEST DEVICE AT STATION OF THAT TYPE
; HIGH=HIGHEST
; (3) GLOBAL GENERIC (E.G. LPT)
; IF DEVICE AT JOB'S STATION, SAME AS STATION GENERIC
; IF NO DEVICE AT JOB'S STATION, SAME AS STATION GENERIC
; AT THE CENTRAL STATION
DEVGEN==CPOPJ## ;THIS UUO NOT SUPPORTED NOW
REPEAT 0,<
DEVGEN: PUSHJ P,DEVSRC ;SEE IF SPECIFIC NAME
JRST DEVGN1 ;NO--TRY GENERIC
IFN FTSPL,<
SKIPL DEVSPL(F) ;SPOOLED DISK?
JRST DEVGN0 ;NO
MOVE T1,DEVNAM(F) ;YES. NAME USER INITED
JRST DEVGEN ;DO THE UUO ON REAL DEVICE
DEVGN0:>
LDB T1,PDVSTA## ;GET STATION NUMBER
LDB T2,PUNIT ;GET UNIT NUMBER
MOVE T3,T2 ;SET OTHER UNIT THE SAME
DEVGNX: HRL T1,T3 ;STORE HIGH UNIT
DPB T2,[POINT 9,T1,8] ;STORE LOW UNIT
PJRST STOTC1## ;SKIP RETURN WITH T1 AS ANSWER
;HERE WHEN NOT A SPECIFIC UNIT
DEVGN1: MOVEI T3,0 ;TAKE ANY DEVICE
PUSHJ P,DVASRC ;TRY GENERIC SEARCH
POPJ P, ;FAILED--RETURN TO USER
LDB T2,PUNIT ;SAVE LOWEST UNIT
LDB T1,PDVSTA## ;GET STATION NUMBER
;LOOP OVER DDB CHAIN GETTING REST OF UNITS
PUSHJ P,SAVE1## ;SAVE P1
DEVGNL: HLLZ T4,DEVNAM(F) ;GET GENERIC NAME
LDB T3,PUNIT ;SAVE HIGH UNIT IN CASE LAST ONE
HLRZ F,DEVSER(F) ;MOVE TO NEXT UNIT
JUMPE F,DEVGNX ;RETURN RESULT IF END OF CHAIN
LDB P1,PDVSTA## ;GET THIS DEVICE'S LOCATION
CAME P1,T1 ;IS IT THE SAME AS WE WANT?
JRST DEVGNX ;NO--RETURN RESULT TO USER
HLLZ P1,DEVNAM(F) ;YES--GET IT'S GENERIC NAME
CAMN P1,T4 ;SEE IF IT MATCHES OUR REQUEST
JRST DEVGNL ;YES--LOOP ONWARDS
JRST DEVGNX ;NO--ALL DONE, RETURN RESULT
>;END OF REPEAT ZERO
SUBTTL GETPPN AND DEVPPN UUO'S (ALSO RTZER)
;RETURN PROJECT-PROGRAMMER NUMBER IN AC
GETPPN:
IFN FTLOGIN,<
MOVSI T1,JACCT
TDNE T1,JBTSTS##(J) ;LOGIN OR LOGOUT CUSP RUNNING ?
JRST GETPPL ;YES, SPECIAL PROJ,R NUMBER CHANGE.
MOVE T1,JBTPPN##(J) ;NO, RETURN PROJECT-PROGRAMMER NO. OF THIS JOB.
JRST STOTAC##
>
RTZER1::AOSA (P) ;RETURN 0 AND SKIP RETURN
RTZERP: POP P,T1 ;POP STACK & RETURN 0
IFE FT2REL, <
SETUWP: ;SETUWP RETURNS 0
>
IFE FT2SEGMON,<
PEEKHI:
>
IFE FTPEEKSPY,<
UPEEK:
>
RTZER:: TDZA T1,T1 ;RETURN 0. TO USER AC
RTM1:: SETOM T1 ;RETURN -1
JRST STOTAC## ;AS SPECIFIED IN AC FIELD OF HIS UUO
IFN FTDISK,<IFN FT5UUO,<
DEVPPU: PUSHJ P,DVCNSG ;FIND DDB
JRST RTZER ;NOT A DEVICE - RETURN 0
PUSHJ P,CURPPX##
MOVSI T2,DVDSK
TDNN T2,DEVMOD(F) ;IS DEVICE A DISK?
JRST STOTAC## ;NO, ERROR RETURN
JRST STOTC1## ;STORE ANSWER AND RETURN
>>
IFE FT5UUO,<
DEVPPU: POPJ P,
>
SUBTTL IONDX. UUO
IFN FT5UUO,<
;CALLI TO CONVERT CHANNEL # OR DEVICE NAME TO I/O INDEX
;CALL WITH:
; MOVE AC,DEVICE NAME OR CHANNEL #
; IONDX. AC, OR CALLI 127
; ERROR RETURN
; GOOD RETURN UNIVERSAL I/O INDEX IN AC
UIONDX::PUSHJ P,IONDX ;FIND THE IO INDEX
JRST STOTAC## ;STORE ERROR CODE
JRST STOTC1## ;STORE IO INDEX
;SUBROUTINE TO FIND IO INDEX. SAME AS UIONDX EXCEPT USER'S AC IS LEFT
; ALONE
IONDX:: PUSHJ P,DVCNSG ;FIND A DDB
PJRST ZPOPJ ;RETURN 0 IF NO SUCH DEVICE
IONDF:: FRAME <NDXARG,NDXNAM>
MOVEM T1,NDXARG
MOVE T1,DEVNAM(F)
MOVEM T1,NDXNAM
PUSHJ P,TTYKLQ## ;KILL OFF DDB IF DDB
; NOT NEEDED
MOVE T1,NDXNAM ;GET DEVICE NAME IN T1
PUSHJ P,TTYALL## ;SET UP U VIA SIXBIT NAME
JRST DEVUDX ;TRY HARDER IF NOT A TTY
LDB T1,LDPLNO## ;GET LINE NUMBER
ADDI T1,.UXTRM ;CONVERT TO I/O INDEX
PJRST CPOPJ1## ;STORE IN AC AND SKIP
DEVUDX: LDB T1,PDVTYP## ;GET THE DEVICE TYPE
MOVE T3,T1
LSH T1,9 ;ALLOW FOR UNIT NUMBER
LDB T2,PUNIT## ;PICK UP UNIT NUMBER
IFN FTRDX,<
CAIN T3,.TYRDA/.TYEST ;RDX DEVICE
ANDI T2,7 ;YES, ONLY LOW ORDER 3 BITS
>;END FTRDX
IOR T1,T2 ;SQUISH TOGETHER
JUMPE T1,DSKUDX ;IF RESULT=0 WE HAVE A DISK AND WANT TO DO
; SOME SPECIAL THINGS.
LDB T2,PDVSTA##
LSH T2,3
CAIE T3,.TYTTY/.TYEST
CAIN T3,.TYPTY/.TYEST
SKIPA
IOR T1,T2
IFN FTRDX,<
CAIN T3,.TYRDA/.TYEST ;RDX DEVICE
JRST DEVUD1 ;YES
>;END FTRDX
CAIE T3,.TYMTA/.TYEST;IS THIS A MAG TAPE
CAIN T3,.TYDTA/.TYEST; OR A DEC TAPE?
SKIPA ;YES--SEE IF THIS IS 2ND CONTROL
PJRST CPOPJ1## ;GOOD RETURN
DEVUD1: LDB T2,[POINT 6,DEVNAM(F),17] ;GET THIRD LETTER
SUBI T2,' A'
LSH T2,^D15
ADD T1,T2
JRST CPOPJ1## ;GOOD RETURN
DSKUDX: MOVE T1,NDXARG
MOVN T3,USRHCU## ;NEGATIVE # OF CHANNELS IN USE
HRLZI T3,-1(T3) ;PUT IN LEFT HALF
DSUDX1: HRRZ T2,USRJDA##(T3) ;GET DDB ADRESS
CAIE T2,0(F) ;DVCNSG FIND THIS DDB?
CAMN T1,DEVNAM(T2) ;DID WE FIND A CHAN FOR THIS DDB?
SKIPA T1,T3 ;YES--COPY CHAN # AND EXIT
AOBJN T3,DSUDX1 ;NO--KEEP LOOKING
TLZ T1,-1 ;MAKE SURE LH=0
JUMPL T3,CPOPJ1## ;GIVE GOOD RETURN IF FOUND
>;END IFN FT5UUO
ZPOPJ: TDZA T1,T1 ;SET T1 = 0
M1POPJ: MOVNI T1,1 ;SET T1 = -1
POPJ P,0 ;RETURN
SUBTTL SUBROUTINE TO FIND A DDB GIVEN ITS IO INDEX
IFN FT5UUO,<
;SUBROUTINE TO FIND A DDB GIVEN ITS UNIVERSAL IO INDEX
;CALL WITH:
; MOVE T1,IO-INDEX
; PUSHJ P,UDXDDB
; BAD UDX OR NO SUCH DEVICE
; HERE WITH F POINTING TO THE DDB
;
;NOTE: THIS ROUTINE IS NOT VERY FAST. DO NOT CALL IT UNLESS
; THERE IS NO OTHER WAY TO SETUP F. IN PARTICULAR, DO NOT
; CALL UDXDDB ON IN OR OUT UUOS.
;
UDXDDB::TLNE T1,-1 ;IS LH=0
POPJ P,0 ;NO--INSTANT LOOSER
CAIGE T1,20 ;0 TO 20 ARE I/O CHANNELS
PJRST DVCNSG ;GO SEE IF OPEN -- SKIP RETURN IF YES
CAIGE T1,1000 ;20 THRU 777 ARE RESERVED
POPJ P,0 ; SO THEY ALL FAIL
LDB T2,[POINT 3,T1,20] ;GET CONTROLLER NUMBER
PUSH P,T2
CAIN T2,2 ;MATCH SPECIAL CODE FOR TTY?
JRST [TRNE T1,577000 ;IS THIS A POSSIBLE TTY
JRST UDXDB1 ;NO, CONTINUE
TRZN T1,.UXTRM ; CHECK FOR A TTY
JRST T2POPJ## ;NO EXIT
SETZM (P) ;YES
PUSH P,[SIXBIT .TTY.] ;ELSE ASSUME TTY #
MOVEI T2,.TYPTY/.TYEST ;SET T2 IN CASE VIRTUAL TTY
JRST UDXDB2] ;AND GO LOOK FOR IT
UDXDB1: LDB T2,[POINT 6,T1,26] ;PICK UP DEVICE TYPE
CAILE T2,TYPMAX ;SKIP IF NOT TOO BIG
JRST T2POPJ## ;TOO BIG--BOMB OUT
PUSH P,TYPTAB(T2) ;ELSE SAVE GENERIC NAME
UDXDB2: ANDI T1,777 ;JUST UNIT NUMBER
CAIN T1,777 ;GENERIC ONLY?
JRST UDXDB4 ;YES--GO DO GENERIC THING
MOVE T3,-1(P) ;GET BACK CONTROLLER NUMBER
JUMPE T3,UDXDB3
ADDI T3,'A' ;CONVERT TO LETTER
DPB T3,[POINT 6,(P),17] ;STORE IN DEVICE NAME
UDXDB3: PUSH P,T2
PUSHJ P,CVTSBT ;CONVERT UNIT NUMBER TO SIXBIT
POP P,T2
CAIN T2,.TYPTY/.TYEST ;NO LEADING O'S FOR PTY
JRST UDXDB4
TLNN T1,77 ;3 DIGITS?
JRST [LSH T1,-6 ;NO, SHIFT ONE DIGIT
TLO T1,(20B5) ;INSERT A LEADING SIXBIT 0
JRST .-1]
UDXDB4: HLRM T1,(P) ;STORE NUMBER
POP P,T1 ;PUT INTO T1 FOR DEVSRG
POP P,T2
PJRST DEVSRG ;GO LOOK FOR THE DDB
DEFINE TYPES(X),<
IRP X,<
<SIXBIT \X\>
>>
TYPTAB: TYPES <DSK,DTA,MTA,TTY,PTR,PTP,DIS,LPT,CDR>
TYPES <CDP,PTY,PLT,EPA,MPX,PAR,PCR,PAP,LPC,PCP,WTY,TSK>
TYPES <XXI,RDA,MCR>
>;END FT5UUO
SUBTTL GTNTN./GTXTN. UUO'S FOR TTY NAMES
IFN FT5UUO,<
;CALLI 165 (GTNTN) RETURN THE PHYSICAL NODE NUMBER AND TTY NUMBER
;CALL WITH:
; MOVE AC,[SIXBIT /TTYNNN/]
; GTNTN. AC,
;RETURN CPOPJ ;TTY DOES NOT EXIST / NOT CONNECTED
;AC=XWD NODE NUMBER,LINE NUMBER
;ERRORS:
; 0: NO SUCH DEVICE
; 1: NOT A TTY
; 2: TTY NOT CONNECTED
GTNTN: PUSHJ P,DVCNSG ;GET THE DDB
PJRST ECOD0## ;NO SUCH DEVICE
MOVSI T2,DVTTY ;GET THE TTY BIT
TDNN T2,DEVMOD(F) ;IS IT?
PJRST ECOD1## ;NOPE
MOVE U,DDBLDB##(F) ;GET THE LDB
IFN FTNET,<
MOVEI T1,LDRREM## ;GET THE REMOTE BIT
TDNN T1,LDBDCH##(U) ;NETWORK TTY?
JRST GTNTN1 ;NO, LOCAL TTY
HLRZ T2,LDBREM##(U) ;IS THE TTY CONNECTED?
PJUMPE T2,ECOD2## ;NOPE, TELL USER
LDB T1,LDPRLN## ;GET THE REMOTE LINE NUMBER
HLL T1,NDBNNM##(T2) ;INSERT THE NODE NUMBER
PJRST STOTC1## ;EXIT
GTNTN1:
> ;END IFN FTNET
LDB T1,LDPLNO## ;GET THE LINE NUMBER
IFN FTNET,<
HRL T1,JBTLOC## ;GET THE LOCAL NODE NUMBER
>
PJRST STOTC1## ;RETURN THE NODE,,LINE
;CALLI 166 (GTXTN) RETURN THE -10'S TTY NUMBER GIVER NODE AND LINE
;CALL WITH:
; MOVE AC,[XWD NODE,LINE]
; GTXTN AC,
;RETURN CPOPJ ;TTY/NODE DO NOT EXITS/NOT CONNECTED
; CPOPJ1 ;AC=SIXBIT /TTYNNN/
;ERRORS:
; 0: UNKNOWN NETWORK TTY
; 1: NO SUCH LOCAL TTY
GTXTN: HLRZ T2,T1 ;GET THE NODE NUMBER
IFN FTNET,<
CAME T2,JBTLOC## ;LOCAL NODE?
>
SKIPN T2 ;ZERO IS ALSO THE LOCAL NODE
JRST GTXTN4 ;LOCAL NODE
IFE FTNET,<
PJRST ECOD0## ;NOT LOCAL RETURN ZERO
>
IFN FTNET,<
SKIPN T4,NETRTY## ;GET THE REMOTE PORTION OF THE SYSTEM'S TTYS
JRST ECOD0## ;NO REMOTE TTYS, RETURN ZERO
GTXTN1: MOVE U,LINTAB##(T4) ;GET THE LDB POINTER
HLRZ T3,LDBREM##(U) ;GET THE NDB POINTER
HLRZ T3,NDBNNM##(T3) ;GET THE NODE NUMBER
JUMPE T3,GTXTN2 ;NOT CONNECTED
CAIE T3,(T2) ;ON THIS NODE?
JRST GTXTN2 ;NO
LDB T3,LDPRLN## ;GET THE REMOTE LINE NUMBER
CAIE T3,(T1) ;IS THIS THE LINE?
GTXTN2: AOBJN T4,GTXTN1 ;NO, CONTINUE THRU LINTAB
JUMPGE T4,ECOD0## ;NOT CONNECTED OR ILLEGAL
GTXTN3: LDB T1,LDPLNO## ;GET THE -10 LINE NUMBER
;RESTORE U
JRST GTXTN5 ;CONVERT AND EXIT
> ;END IFN FTNET
GTXTN4: ANDI T1,-1 ;MAX NUMBER
CAILE T1,TCONLN## ;IN RANGE?
JRST ECOD1## ;NO, NOT A LEGAL TTY
IFN FTNET,<
MOVE T2,LINTAB##(T1) ;GET THE LDB POINTER
MOVEI T3,LDRREM## ;GET NETWORK LINE BIT
TDNE T3,LDBDCH##(T2) ;IS IT A NETWORK TTY?
JRST ECOD1## ;YES, ILLEGAL DEVICE
> ;END IFN FTNET
GTXTN5: PUSHJ P,CVTSBT ;NO, CONVERT TO SIXBIT
HLRZ T1,T1 ;RIGHT HALF
HRLI T1,'TTY' ;INSERT TTY NAME
PJRST STOTC1## ;EXIT THE UUO
> ;END FT5UUO
SUBTTL MVBFH. UUO -- MOVE BUFFER HEADERS
IFN FT5UUO,<
;SUBROUTINE TO MOVE BUFFER HEADERS
;CALL WITH:
; MOVE AC,CHANNEL-NUMBER
; MOVE AC+1,[NEW-OUTPUT,,NEW-INPUT]
; MVBFH. AC,
; ERROR RETURN
; GOOD RETURN
MOVHDR: PUSHJ P,SAVE1## ;SAVE UCHAN
HRRZ P1,T1 ;COPY CHANNEL NUMBER
LDB T1,PUUOAC## ;GET AC #
HRRI M,1(T1) ;PLUS 1
PUSHJ P,GETWDU## ;PICK UP THE WORD
CAMG P1,USRHCU## ;SKIP IF CHANNEL # TOO BIG
SKIPN F,USRJDA##(P1) ;SKIP IF CHANNEL INITED
JRST ECOD1## ;ERROR -- BAD CHANNEL NUMBER
PUSH P,T1 ;SAVE ARG
HLRZ T2,T1 ;GET OUTPUT BUFFER ADDRESS
JUMPE T2,MVBFH1 ;JUMPE IF NO CHANGE
HRLM T2,DEVBUF(F) ;STORE NEW ADDRESS
TLON F,OBUFB ;TEST AND SET "OUTPUT BUFFER EXISTS" FLAG
PUSHJ P,UINITZ ;NEW BUFFER
MVBFH1: HRRZ T2,(P) ;GET INPUT POINTER
JUMPE T2,MVBFH2 ;JUMP IF NO CHANGE
HRRM T2,DEVBUF(F) ;SAVE NEW ADDRESS
TLON F,IBUFB ;FLAG WE HAVE INPUT BUFFER
PUSHJ P,UINITZ ;NEW BUFFER
MVBFH2: MOVEM F,USRJDA##(P1) ;SAVE UPDATED FLAGS
JRST TPOPJ1## ;GOOD RETURN
> ;END FT5UUO
IFE FT5UUO,< MOVHDR==CPOPJ## >
SUBTTL DEVSTS, DEVLNM, DEVRST, AND DEVURS UUO'S
IFN FT5UUO,<
;DEVICE STATUS CONI RETRIEVAL CALLI UUO
; CALL AC,[SIXBIT/DEVSTS/]
; OR
; CALLI AC,54
; WHERE AC CONTAINS THE CHANNEL NUMBER OF THE
; INIT'ED DEVICE....
; OR DEVICE NAME
; THE CONI STATUS WORD IN THE DDB (DEVSTS)
; IS RETURNED IN AC
DEVST: PUSHJ P,DVCNSG ;SEARCH FOR DEVICE OR CHANNEL
JRST RTZER ;RETURN 0 IF NOT THERE
MOVE T1,DEVSTS(F) ;GET DEVICE STATUS WORD
JRST STOTC1## ;USER, RETURNING T1 IN AC
IFN FTREAS,<
;CALLI TO SET LOGICAL NAME
; MOVE AC,SIXBIT/DEVICE NAME/OR CHAN. NO.
; MOVE AC+1,SIXBIT/LOGICAL NAME/
; DEVLNM AC,
; ERROR RETURN ;AC=-1 IF NON-EX DEV. OR CHAN;-2 IF LOGICAL NAME IN USE
; NORMAL RETURN
DEVLNM: PUSHJ P,DVCNSG ;FIND DDB FOR THIS DEVICE
PJRST RTM1 ;CAN'T--ERROR RET. WITH AC=-1
LDB T2,PJOBN##
MOVE T1,DEVMOD(F) ;DEVICE INITED OR ASSIGNED?
CAMN T2,J ;MY DEVICE
TRNN T1,ASSCON!ASSPRG
JRST DEVLN3 ;NO, RETURN -3
PUSHJ P,SAVE1## ;SAVE P1
PUSHJ P,GETWD1## ;GET LOGICAL NAME
MOVE P1,F ;SAVE DDB ADDR.
PUSHJ P,DEVLG ;IS ALREADY USED?
JRST DEVLN1 ;NO--
CAME F,P1 ;YES--SAME DEVICE?
SOJA M,DEVLN2 ;NO--ERROR RET -2
DEVLN1:
IFN FTDISK,<
CAIN P1,DSKDDB## ;DON'T CHANGE PROTYPE DSK DDB
JRST CPOPJ1##
>
MOVEM T1,DEVLOG(P1) ;YES--SET LOGICAL NAME
MOVE F,P1 ;RESTORE F FOR ASSCHK AND SETDVL
PUSHJ P,SETDVL ;BE SURE LOG. NAME TABLE IS OK.
SKIPN DEVLOG(F) ;CLEARING LOGICAL NAME?
PUSHJ P,ASSCK1## ;YES, SEE IF WE CAN RECLAIM SPACE
JRST CPOPJ1## ; AND GIVE GOOD RETURN
DEVLN3: SKIPA T1,[-3]
DEVLN2: MOVNI T1,2 ;RETURN -2 IN USER AC
PJRST STOTAC##
> ;IFN FTREAS
IFE FTREAS,<DEVLNM==CPOPJ##>
> ;END CONDITIONAL ON FT5UUO
IFE FT5UUO,<
DEVLNM==CPOPJ##
DEVST==CPOPJ##
>
IFN FT5UUO,<
;CALLI'S TO SET AND CLEAR THE RESTRICTED
;ASSIGNMENT BIT (DEPRAS) IN DEVSTA. LIMITED
;TO [1,2] OR JACCT SET.
; MOVE AC,[SIXBIT /DEVICE NAME/] OR CHANEL NO.
; DEVRST. AC, ;TO RESTRICT DEVICE
; DEVURS. AC, ;TO UNRESTRICT DEVICE
; ERROR RETURN ;NOT PRIVILEDGED, OR NON-EXISTANT DEVICE
; NORMAL RETURN
DEVRST: PUSHJ P,PRVJ## ;SKIP IF NOT PRIVILEDGED
PUSHJ P,DVCNSG ;SEARCH FOR DDB AND SKIP IF FOUND
POPJ P, ;ERROR (NON-SKIP) RETURN
MOVSI T1,DVDSK
IFN FTSPL,<
SKIPE DEVCHR(F)
>
TDNE T1,DEVMOD(F) ;IS IT A DISK?
POPJ P, ;YES, DON'T RESTRICT DISKS
MOVSI T1,DEPRAS ;GET RESTRICTED ASSIGNMENT BIT
IORM T1,DEVSTA(F) ;SET BIT IN DDB
PJRST CPOPJ1## ;AND SKIP RETURN
DEVURS: PUSHJ P,PRVJ## ;SKIP IF NOTPRIVILEDGED
PUSHJ P,DVCNSG ;SEARCH FOR DDB AND SKIP IF FOUND
POPJ P, ;ERROR (NON-SKIP) RETURN
MOVSI T1,DEPRAS ;GET RESTRICTED ASSIGNMENT BIT
IFN FTSPL,<
SKIPE DEVCHR(F) ;IF NOT A SPLTAB ENTRY
>
ANDCAM T1,DEVSTA(F) ;CLEAR THE BIT IN DDB
PJRST CPOPJ1## ;AND SKIP RETURN
> ;END FT5UUO
IFE FT5UUO,<
DEVRST==CPOPJ##
DEVURS==CPOPJ##
>
SUBTTL SETDDT, WAIT AND GETLIN CALLI'S ; WAIT2 AND GETPPL
SETDDT: MOVEM T1,JOBDDT##(R) ;SET BOTH USRDDT & JOBDDT IN JOB DATA AREA IN CASE
IFE FTVM,<
MOVEM T1,.CPDDT##(P4) ;LOCATION IN PROTECTED JOB DATA AREA
>
IFN FTVM,<
MOVEM T1,USRDDT## ; USER LOOKS AT JOBDDT BEFORE RESCHEDULING OCCURS
>
POPJ P, ;RETURN TO USER
IFN FTLOGIN, <
GETPPL: MOVE T1,JBTPPN##(J) ; AND GET OLD NUMBERS.
MOVE T2,HIGHJB## ;CHECK FOR OTHER USERS UNDER SAME PP NUMBER.
PPNLUP: CAIN T2,(J) ;IS NEXT JOB TO BE LOOKED AT CURRENT JOB ?
SOJLE T2,STOTAC## ;YES, FINISHED SCANNING ALL JOBS ?
CAMN T1,JBTPPN##(T2) ;NO, ANOTHER USER UNDER SAME PROJ,R NUMBER ?
JRST STOTC1## ;YES, SKIP RETURN TO USER (LOGIN OR LOGOUT)
SOJG T2,PPNLUP ;NO, KEEP LOOKING
JRST STOTAC## ;NO OTHER JOBS, GIVE NORMAL RETURN
>
IFE FTLOGIN,<
GETPPL==CPOPJ##>
GETLN: PUSHJ P,TTYFND## ;FIND USER'S TTY DATA BLOCK.
MOVE T1,DEVNAM(F) ;GET DEVICE NAME IN SIXBIT
JRST STOTAC## ;RETURN IT TO USER.
;WAIT FOR IO TO BECOME INACTIVE ON CHANNEL AC
WAIT:: JUMPE F,CPOPJ## ;CHANNEL ASSIGNED?
; JRST WAIT2 ;WAIT TILL INACTIVE BEFORE
; RETURNING TO USER.
;ROUTINE TO ENSURE THAT ALL OUTPUT BUFFERS HAVE BEEN WRITTEN
WAIT2:
WAIT2X: PUSHJ P,WAIT1## ;NO, WAIT TILL INACTIVE
HLRZ U,DEVBUF(F) ;L(BUF)
JUMPE U,CPOPJ## ;NONE-RETURN
LDB T1,PIOMOD##
CAIGE T1,SD ;BUF MODE?
TLNN F,OUTBFB+OUTPB ;YES, ANY BUFFERS?
POPJ P, ;NO
IFN FTMSGSER,<
LDB T1,PDVTYP## ;DEVICE TYPE
CAIN T1,.TYMPX/.TYEST;MPX?
PJRST MPXWAT## ;YES, WAIT MPX STYLE
>
IFN FTKA10,<
HRLI U,R
>
HRRZ T1,U
PUSHJ P,UADRCK ;ADDRESS CHECK THE HEADER
TLNE S,IO ;RETURN IF OUTPUT WASN'T LAST
EXCTUX <SKIPG @U> ;YES, VIRGIN RING?
POPJ P, ;YES, RETURN
PUSH P,DEVAIO(F)
MOVEI T1,DEPAIO!DEPOND;NON-BLOCKING BIT AND OUTPUT NOT DONE BIT
ANDCAM T1,DEVAIO(F) ;MAKE SURE THAT THIS WAITS UNTIL BUFFERS ARE OUT
;FALL INTO WAIT2A
WAIT2A: HRR U,DEVOAD(F)
HRRZ T1,U
JUMPE T1,WAIT2B ;RETURN IF REALLY NO OUTPUTS
PUSHJ P,UADRCK ;ADDRESS CHECK THE BUFFER ITSELF
EXCTUX <SKIPL @U> ;BUFFER HAVE DATA?
JRST WAIT2B ;NO, DONE
IFN FTVM,<
PUSHJ P,BRNGE## ;MAKE SURE ENTIRE DEVOAD BUFFER IS IN CORE
>
TRZ S,760000 ;YES, CLEAR ERROR BITS
PUSH P,U
PUSH P,M
PUSHJ P,CALOUT ;CRANK UP THE DEVICE
POP P,M
POP P,U
PUSHJ P,WAIT1##
TRNE S,760000 ;ERRORS ENCOUNTERED?
JRST WAIT2B ;YES, GIVE UP
MOVSI T1,DEPSIE ;STOP ON ERROR BIT
TDNE T1,DEVJOB(F) ;IS IT ON?
TRNN S,IOTEND ;AND END OF TAPE?
JRST WAIT2A ;NO, RESTART IO IF NOT ALL BUFS DONE
WAIT2B: HRRZ T4,DEVSER(F) ;YES, RESTORE T4 = DISPATCH ADR
POP P,T1
ANDI T1,DEPAIO+DEPOND
IORM T1,DEVAIO(F)
POPJ P, ;AND RETURN
IFN FTLOGIN&FTACCT,<
SUBTTL ACCT. UUO - ACCOUNTING UUO
;UUO TO PERFORM ACCOUNTING FUNCTIONS
;CALLING SEQUENCE:
; MOVE AC,[FUNCTION,,ADDRESS]
; ACCT. AC,
; ERROR RETURN
; NORMAL RETURN
ACCT: HLRZ U,T1 ;FUNCTION
CAILE U,NLACCT ;DEFINED?
JRST ACTIAL ;NO, ILLEGAL
HRR M,T1 ;ADDRESS OF ARGUMENT BLOCK
PUSHJ P,GETWRD## ;GET LENGTH OF ARGUMENT BLOCK
JRST ACTADC ;ADDRES CHECK
JRST @ACTTBL(U) ;DISPATCH
ACTTBL: ACTCAS
ACTRAS
NLACCT==.-ACTTBL-1
;HERE TO CHANGE THE ACCOUNT STRING
ACTCAS: MOVEI T2,ACTSTL## ;LENGTH OF ACCOUNT STRING
JUMPE T2,CPOPJ## ;NOT IMPLEMENTED IF LENGTH EQUALS ZERO
MOVSI T2,JACCT ;IS HE?
TDNN T2,JBTSTS##(J) ;NO, ERROR
JRST ACTNPV ;NO, ERROR
CAIE T1,1 ;ARGUMENT LIST MUST CONTAIN EXACTLY ONE WORD
JRST ACTIAL ;ILLEGAL ARGUMENT LIST
PUSHJ P,GETWR1## ;GET BYTE POINTER TO ACCOUNT STRING
JRST ACTADC ;ADDRESS CHECK
PUSHJ P,CKSTR ;MAKE SURE THE STRING IS LEGAL AND IN CORE
JRST ACTADC ;ADDRESS CHECK
PUSHJ P,SAVE1## ;SAVE P1
MOVSI P1,MACTSL## ;MINUS THE MAXIMUM LENGTH OF AN ACCOUNTING STRING
HRRI P1,.PDACS##(W) ;WHERE TO STORE ACCOUNT STRING
HRRI M,-1(T1) ;ADDRESS OF NEW ACCOUNT STRING
ACTCA1: PUSHJ P,GETWD1## ;GET NEXT WORD
MOVEM T1,(P1) ; AND STORE IT IN THE PDB
AOBJN P1,ACTCA1 ;LOOP OVER ENTIRE STRING
LDB T1,LSTBAS## ;LAST BYTE IN THE ACCOUNT STRING
MOVEI T2,0 ;LAST BYTE MUST BE ZERO
DPB T2,LSTBAS## ;ZAP
JUMPN T1,ACTTLS ;ERROR IF LAST BYTE ISN'T ZERO
JRST CPOPJ1## ;GOOD RETURN
;HERE TO READ THE ACCOUNT STRING
ACTRAS: MOVEI T2,ACTSTL## ;LENGTH OF THE ACCOUNT STRING
JUMPE T2,CPOPJ## ;NOT IMPLEMENTED IF ZERO
CAIE T1,2 ;ARGUMENT LIST MUST BE EXACTLY TWO WORDS LONG
JRST ACTIAL ;ILLEGAL ARGUMENT LIST
PUSHJ P,GETWR1## ;GET JOB NUMBER
JRST ACTADC ;ADDRESS CHECK
CAME T1,[-1] ;MINUS ONE MEANS CURRENT JOB
MOVE J,T1 ;TARGET JOB NUMBER
PUSHJ P,FNDPDB## ;FIND JOB'S PDB
JRST ACTNSJ ;NO SUCH JOB
PUSHJ P,GETWR1## ;GET ADDRESS WHERE A.S. SHOULD BE STORED
JRST ACTADC ;ADDRESS CHECK
HRRI M,ACTSTL##(T1) ;LAST ADDRESS WHERE A.S. TO BE STORED
PUSHJ P,GETWRD## ;CHECK LEGALITY
JRST ACTADC ;BAD ADDRESS
HRRI M,MACTSL##-1(M) ;SET TO STORE ACCOUNT STRING
MOVSI T2,MACTSL## ;NEGATIVE LENGTH
HRRI T2,.PDACS##(W) ;ADDRESS OF THE ACCOUNT STRING
ACTRA1: MOVE T1,(T2) ;WORD FROM ACCOUNT STRING
PUSHJ P,PUTWD1## ;STORE IT FOR THE PROGRAM
AOBJN T2,ACTRA1 ;LOOP OVER THE ENTIRE ACCOUNT STRING
JRST CPOPJ1## ;GOOD RETURN
;ACCT. ERROR CODES
ERCODE ACTTLS,1 ;STRING TO LONG
ERCODE ACTADC,2 ;ADDRESS CHECK
ERCODE ACTIAL,3 ;ILLEGAL ARGUMENT LIST
ERCODE ACTNSJ,4 ;NO SUCH JOB
ERCODE ACTNPV,5 ;NOT PRIVILEGED
>
SUBTTL LOGIN, LOGOUT AND ATTACH UUO'S
;LOGIN UUO USED ONLY BY LOGIN AND LOGOUT CUSPS
;CALL: CALL AC,[SIXBIT /LOGIN/]
;WHERE AC CONTAINS XWD -NO. OF ENTRIES,LOCATION
;WHICH IS A LIST OF JOB STATISTICS TO BE STORED IN MONITOR
;RETURNS TO UUO +1 IF SUCCESSFUL AND THAT LOC DOES NOT CONTAIN A HALT
IFN FTLOGIN,<
LOGIN: MOVSI T2,JLOG ;IS USER ALREADY LOGGED IN?
TDNE T2,JBTSTS##(J)
POPJ P, ;YES, NO-OP
PUSHJ P,SAVE2## ;SAVE P1-P2
HLRE P1,T1 ;NO, -NO. OF WORDS
HRR M,T1 ;FIRST REL. LOC.
MOVE P2,[XWD -LOGTOP,LOGTAB] ;SET FOR LOOP
LOGIN1: MOVEI T1,0 ;ASSUME 0
AOSG P1 ;FINISHED HIS COUNT?
PUSHJ P,GTWST2## ;NO, GET NEXT WORD FROM USER AREA
MOVEM T1,@(P2) ;STORE WORD OR 0
ADDI M,1 ;GET NEXT ITEM
AOBJN P2,LOGIN1 ;FINISHED NO. OF MONITOR TABLES?
PUSHJ P,SETLOG## ;SET JLOG, INCREMEN LOGNUM, BATNUM
IFN FTGALAXY,<
PUSHJ P,QSRLGI##
> ;END IFN FTGALAXY
MOVSI T2,JACCT ;RESET THIS BIT TO INDICATE LOG-IN IS
HRRI T2,JS.XO ; AND CLEAR EXECUTE ONLY
ANDCAM T2,JBTSTS##(J) ; NOW COMPLETE AND ^C IS AGAIN PERMITTED.
HRRZ M,JOBPD1##(R) ;LOCATION OF UUO IN USER AREA
PUSHJ P,GETWDU## ;GET NEXT INSTR FROM USER AREA
LSH T1,-30 ;LOOK AT TOP 12 BITS
CAIE T1,<HALT>B<35+24> ;HALT?
POPJ P,0 ;NO. RETURN TO USER.
LOGIN2: PUSHJ P,IORELS ;RELEASE ALL DEVICES
PUSHJ P,TTYFUW## ;FIND TTY AND PRINT ^C
JRST HOLD##
;STILL IN FTLOGIN CONDITIONAL
;TABLE OF POINTERS TO TABLES(STORED WITH JOB NUMBER AS INDEX)
;TO MAKE LOGIN SET MORE TABLES IN MONITOR, JUST ADD TABLE NAMES AT END
LOGTAB: XWD J,JBTPPN## ;PROJECT-PROGRAMMER NUMBER
IFN FTPRV,<
XWD J,JBTPRV## ;JOB PRIVILEGE BITS
>
IFE FTPRV,<
IFN FTUNAME!FTCNO,<
;KEEP THESE IF ANY ENTRIES FOLLOW
EXP S ;STORE IN AC S, SINCE PRIVILEGE TABLE DOES NOT EXIST
>>
IFN FTUNAME,<
XWD W,.PDNM1## ;1ST HALF OF USER'S NAME
XWD W,.PDNM2## ;2ND HALF OF USER'S NAME
>
IFE FTUNAME,<
IFN FTCNO,<
;KEEP THESE IF ANY ENTRIES FOLLOW
EXP S
EXP S
>>
IFN FTCNO,<
XWD W,.PDCNO## ;CHARGE NUMBER THIS JOB
>
IFE FTCNO,<
REPEAT 0,<
;KEEP THESE IF ANY ENTRIES FOLLOW
EXP S
>>
LOGTOP==.-LOGTAB ;NO. OF TABLES TO BE SET
> ;END CONDITIONAL ON FTLOGIN
;LOGOUT UUO
LOGOUT: PUSHJ P,TTYFNU##
IFN FTLOGIN,<
MOVE T1,JBTSTS##(J) ;JOB STATUS
TLNN T1,JLOG ;LOGGED IN?
JRST JOBKL## ;NO
TLNN T1,JACCT ;ONLY A REAL, LIVE
;JACCTED LOGOUT
JRST EXIT ;IS ALLOWED TO DO THIS
MOVE T1,JBTPRG##(J) ;FOR EVERYBODY WLSE,
CAME T1,[SIXBIT .LOGOUT.] ;TREAT JUST LIKE EXIT
JRST EXIT
>
JRST JOBKL##
IFE FTLOGIN,<
LOGIN=CPOPJ## ;CANT DO A LOGIN UUO
>
;ATTACH UUO - PRIVILEGED, FOR DAEMON, ATTACH COMMAND.
IFE FTATTACH,<UATTAC==CPOPJ##>
IFN FTATTACH,<
UATTAC: PUSHJ P,SAVE1## ;SAVE P1
HLLZ P1,T1 ;P1=FLAGS
PUSH P,T1 ;SAVE ARG XWD LINE, JOB
IFN FTLOGIN,< PUSHJ P,PRVJ## ;IS THIS A PRIVILEGED JOB?
SKIPA T1,0(P) ;YES. RESTORE ARGUMENT.
JRST UATAC5 ;NO. GO
>
TRNE T1,400000 ;NEGATIVE JOB ARGUMENT?
JRST UATC1A ;YES, MIGHT BE LINE CHANGE
TRNE T1,-1 ;ZERO ARGUMENT?
JRST UATAC1 ;NO. WANTS ATTACH.
HLRZ T1,0(P) ;YES. WANTS DETACH DONE
TRZ T1,600000 ;CLEAR FLAGS
CAIE T1,177777 ;DETATCH SELF?
JRST UATAC2 ;NO.
PUSHJ P,TTYSRC## ;FIND DDB VIA J
JRST TPOPJ## ;SHOULDN'T FAIL, NO DDB THIS JOB?
UATAC3: PUSHJ P,TTYDET## ;DETACH VIA F
SKIPE LDBBKC##(U) ;ANY BREAK CHARACTERS INPUT?
PUSHJ P,COMSET## ;YES, ASSUME COMMAND TYPED
JRST TPOPJ1## ;GIVE USER OK RETURN
UATAC2: CAIL T1,TTPLEN## ;LEGAL LINE NUMBER?
JRST TPOPJ## ;NO. GIVE FAIL RETURN.
HRRZ U, LINTAB##(T1) ;YES. GET THE LDB ADDRESS
HRRZ F,LDBDDB##(U) ;GET LINKED DDB, IF ANY
JUMPE F,TPOPJ1## ;ALREADY DETACHED. GIVE OK RETURN
JRST UATAC3 ;GO DETACH JOB.
UATAC1: HRRZS T1 ;JOB NUMBER OF JOB BEING ATTACHED TO
PUSHJ P,LGLPRC## ;IS IT A LEGAL JOB NUMBER?
JRST TPOPJ## ;NO, FAIL RETURN
SKIPA T1,(P) ;YES, RESTORE JOB NUMBER
UATC1A: HRR T1,J ;NEGATIVE JOB ARGUMENT MEANS SELF
HRRZ F,TTYTAB##(T1) ;DDB OF JOB DESIRED
JUMPE F,TPOPJ## ;IF NONE, FAIL RETURN
MOVSI U,600000 ;FLAG BITS TO CLEAR
ANDCAM U,0(P) ;ZAP!
HLRZ U,0(P) ;GET LINE NUMBER REQUESTED
CAIL U,TTPLEN## ;IS IT LEGAL?
JRST TPOPJ## ;NO. FAIL RETURN.
MOVEI T3,LDRDSR##
MOVE T2,LINTAB##(U) ;"TO" TTY
CAIG U,TCONLN##
TDNE T3,LDBDCH##(T2) ;ATTACHIN TO LOCAL TTY?
JRST UATC1C ;NO, OK
UATC1D: MOVE T2,TTYTAB##(T1) ;YES, "FROM" TTY
HRRZ U,DDBLDB##(T2)
MOVE T1,JBTPPN##(J) ;GOING FROM A LOCAL TTY?
CAME T1,HELPPP##
CAMN T1,FSFPPN## ;OR A PRIV'D JOB?
JRST UATC1C
MOVE T3,LDBDCH##(U)
TRNN T3,LDRPTY##
TRNE T3,LDRDSR##
JRST TPOPJ ;CANT DO IT
UATC1C: PUSHJ P,PTYDET## ;DETACH VIA F
HLRZ U,0(P) ;GET LINE NUMBER
HRRZ U,LINTAB##(U) ;GET LDB ADDRESS
LDB J,PJOBN## ;GET JOB NUMBER
MOVE T1,(P) ;RESTORE ARGUMENT
TRNN T1,400000 ;JOB ATTACH ?
JRST UATC1B ;YES
HRRM J,(P) ;NO. USE J.
UATC1B: PUSHJ P,TTYATT## ;DO THE ATTACH.
JRST TPOPJ## ;FAIL RETURN (SHOULDN'T HAPPEN)
JUMPGE P1,UATAC4 ;JUMP IF SET TO MONITOR LEVEL FLAG NOT SET
PUSHJ P,CNCMOD## ;SET TO MONITOR LEVEL
JRST TPOPJ1##
UATAC4: MOVSI T1,LDLCOM##
TLNE P1,200000 ;SKIP IF TO SET USER LEVEL
ANDCAM T1,LDBDCH##(U) ;CLEAR MONITOR LEVEL BIT
TDNE T1,LDBDCH##(U) ;SKIP IF AT USER LEVEL
JRST TPOPJ1## ;NO, OK RETURN NOW
LDB T1,PJBSTS##
CAIE T1,TIOWQ##
JRST TPOPJ1##
MOVE T1,DEVIOS(F)
TLNE T1,IOW
PUSHJ P,TTWAKE##
JRST TPOPJ1## ;OK RETURN.
IFN FTLOGIN,<
UATAC5: MOVE T1,(P) ;DET STILL ALOWED (SOMETIMES)
TRNE T1,-1 ;DOES HE WANT A DET?
PJRST TPOPJ## ;NO, RETURN
PUSHJ P,TTYSRC## ;YES, SET UP 4
PJRST TPOPJ## ;SHOULD NEVER FAIL
HLRZ T1,(P) ;GET TTY NUMBER HE WANTED DET'D
CAIN T1,-1 ;IS IT -1? (DEFAULT FOR SELF)
JRST UATAC6 ;YES, CHECK USER MODE
TRZ T1,600000 ;GET RID OF FLAGS
LDB P1,LDPLNO## ;GET REAL TTY NUMBER
CAME T1,P1 ;SAME?
PJRST TPOPJ## ;NO, RETURN
UATAC6: MOVSI T1,LDLCOM## ;MONITOR COMMAND LEVEL BIT
MOVSI P1,(JB.LBT) ;GET BATCH BIT
TDNN P1,JBTLIM(J) ;IS THIS A BATCH JOB?
TDNE T1,LDBDCH##(U) ;IS HIS TTY AT USER LEVEL?
PJRST TPOPJ## ;NO, RETURN
JRST UATAC3 ;YES, NOW DET HIM.
> ;END FTLOGIN CONDITIONAL
> ;END FTATTACH CONDITIONAL
SUBTTL GETTAB UUO
;UUO TO RETURN CONTENTS OF A MONITOR JOB TABLE ENTRY
;CALL: HRROI AC, MONITOR JOB TABLE NUMBER (NEG. TABLES FOR CUSTOMER)
; HRLI AC, JOB NUMBER (OPTIONAL) LH .EQ. -1 MEANS CURRENT JOB
; LH .EQ. -2 MEANS JOB'S HIGH-SEGMENT
; CALL AC, [SIXBIT /GETTAB/] OR CALLI AC,41
; ERROR RETURN AC PRESERVED IF LH OR RH TOO BIG OR
; AC=-1 IF NOT PRIVILIGED TO GET INFO
; NORMAL RETURN - AC=0 IF TABLE IS UNDEFINED
IFN FTGETTAB,<
GETTAB: HLRZ T2,T1 ;GET USER SUPPLIED JOB NUMBER
HRRE T3,T1 ;GET TABLE NUMBER IN T3
CAIGE T3,GTTBLN ;IS TABLE NUMBER LEGAL?
CAMGE T3,MINTBB ; (NEGATIVE NUMBERS LEGAL FOR CUSTOMER'S TABLES)
POPJ P, ;NO. ERROR RETURN, AC UNCHANGED
CAIN T3,GTSELF ;IS THIS A GETTAB IMMEDIATELY?
JRST GETIMT ;YES--GO HANDLE SPECIALLY
CAIGE T2,-2 ;DID HE SUPPLY ONE?
MOVE J,T2 ;YES, USE IT
IFN FT2REL,<IFN FT5UUO,<
SKIPE TWOREG## ;SEE IF HIGH-SEGS
CAIE T2,-2 ;YES--SEE IF REQUESTING HI-SEG
JRST GETTB1 ;NO--SKIP AHEAD
SKIPG J,JBTSGN##(J) ;YES--SEE IF HE HAS A HI-SEG
POPJ P, ;ERROR IF NO HI-SEG
TLZ J,-1
GETTB1:>>
;AT THIS POINT T3=TABLE NUMBER AND J=INDEX
LDB T1,[POINT 3,NUMTAB(T3),11] ;GET CODE
JUMPE T1,CPOPJ## ;JUMP IF UNDEFINED
MOVEI T2,0 ;ASSUME 0 MAX
CAIE T1,GT.JOB ;JOB TABLE?
CAIN T1,GT.PDB ; OR PDB POINTER?
MOVEI T2,JOBMAX## ;YES--SETUP MAXIMUM
CAIN T1,GT.SEG ;JOBN+SEGN LONG?
MOVEI T2,JBTMAX## ;YES--SETUP MAXIMUM
CAIN T1,GT.ITM ;SPECIAL TABLE
LDB T2,[POINT 9,NUMTAB(T3),8] ;GET MAXIMUM
JUMPE T2,RTZER1 ;IF T2=0 NUMTAB IS WRONG
CAMLE J,T2 ;SKIP IF VALID INDEX
POPJ P,0 ;INDEX IS TOO BIG
CAIE T1,GT.PDB ;IS DATA IN PDB?
JRST GETTBX ;NO--GET FROM TABLE
MOVE T2,J ;COPY INDEX INTO RIGHT AC
HRRZ T3,NUMTAB(T3) ;INDEX INTO PDB
PUSHJ P,PDBWRD## ;GET WORD FROM PDB
JRST STOTC1## ;STORE AS ANSWER
GETTBX: MOVE T1,@NUMTAB(T3) ;GET WORD
JRST STOTC1## ;SKIP RETURN T1 IN HIS AC
GETIMT: HRRE J,T2 ;GET TABLE NUMBER INDEX
JUMPGE J,GETTB1 ;NON-NEGATIVE, DO NORMALLY
CAMGE J,MINTBB ;IS IT IN RANGE?
POPJ P, ;NO--GIVE ERROR RETURN
JRST GETTBX ;YES--RETURN VALUE
;THE MONITOR JOB TABLE NUMBERS:
$LOW ;MUST BE IN LOW SEG FOR GETTAB IMMEDIATE
;MACRO TO DEFINE A GETTAB TABLE
;THIS MACRO HAS 3 ARGUMENTS:
; FT - FEATURE TESTS FOR WHICH TABLE EXISTS
; TYPE - ONE OF:
; "J" - JOB TABLE
; "S"- JOB TABLE WITH JOBN + SEGN ENTRIES
; "I" - RANDOM TABLE
; "P" - DATA IN PDB
; TBL - ADDRESS OF TABLE (OR INDEX INTO PDB)
; MAX - MAXIMUM FOR RANDOM TABLES SHIFTED LEFT 9 BITS
;
DEFINE GT(FT,TYPE,TBL,MAX),<
IFIDN <TYPE>,<J>,<
IFE FT,< JOBMXL##+<GT.JOB>B29,,ZERO>
IFN FT,< JOBMXL##+<GT.JOB>B29+J,,TBL>
>
IFIDN <TYPE>,<S>,<
IFE FT,< JBTMXL##+<GT.SEG>B29,,ZERO>
IFN FT,< JBTMXL##+<GT.SEG>B29+J,,TBL>
>
IFIDN <TYPE>,<P>,<
IFE FT,< JOBMXL##+<GT.JOB>B29,,ZERO>
IFN FT,< JOBMXL##+<GT.PDB>B29+W,,TBL>
>
IFIDN <TYPE>,<I>,<
IFE FT,< ZERO>
IFN FT,< MAX+<GT.ITM>B29+J,,TBL>
>
>
SALL
GTBSTT: ;CUSTOMER TABLES GO HERE
NUMTAB::GT 1,S,JBTSTS## ;(000) JOB STATUS TABLE
MINTAB==GTBSTT-NUMTAB
GT 1,S,JBTADR## ;(001) SIZE,,ADDRESS
GT FTLOGIN,S,JBTPPN## ;(002) PPN
GT 1,S,JBTPRG## ;(003) PROGRAM NAME
GT FTTIME,P,.PDTTM## ;(004) RUNTIME IN JIFFIES
GT FTKCT,P,.PDKCT## ;(005) KCT COUNT
GT FTPRV,J,JBTPRV## ;(006) PRIVILEGE BITS
GT FTSWAP,S,JBTSWP## ;(007) LOCATION ON DISK
GT 1,J,TTYTAB## ;(010) TTY DDB POINTERS
GT 1,I,CNFTBL##,CNFMXL## ;(011) CONFIGURATION DATA
GT 1,I,NSWTBL##,NSWMXL## ;(012) NON-SWAPPING DATA
GT FTSWAP,I,SWPTBL##,SWPMXL## ;(013) SWAPPING DATA
GT FT2REL,J,JBTSGN## ;(014) HIGH SEG #
GT FTDISK,I,ODPTBL##,ODPMXL## ;(015) ONCE ONLY DISK PARAMETERS
GT FTDISK,I,LVDTBL##,LVDMXL## ;(016) LEVEL-D TABLE
GT FTDSTT,J,JBTRCT## ;(017) DISK READS
GT FTDSTT,J,JBTWCT## ;(020) DISK WRITES
EXP ZERO ;(021) UNUSED
EXP ZERO ;(022) UNUSED
GTSELF==.-NUMTAB ;TABLE # OF NUMTAB
GT 1,I,NUMTAB,<<GTTBLN-1>B26> ;(023) THIS TABLE
GT FT2REL,S,JBTDEV## ;(024) DEVICE OR FSN
GT 1,I,STSTBL##,STSMXL## ;(025) STATE CODES
GT FTNET,J,JBTLOC## ;(026) JOB LOCATION
GT 1,I,CORTAB##,CTBMXL## ;(027) KA10 CORE TABLE
GT 1,I,COMTAB##,COMMXL## ;(030) MONITOR COMMANDS*
GT FTUNAM,P,.PDNM1## ;(031) USER NAME (0FIRST)
GT FTUNAM,P,.PDNM2## ;(032) USER NAME (0LAST)
GT FTCNO,P,.PDCNO## ;(033) CHARGE NUMBER
GT FTTMP,I,JBTTMP##,ITMTMP## ;(034) TMPCOR POINTERS
GT FTWATC,J,JBTWCH## ;(035) WATCH BITS
GT FTSPL,J,JBTSPL## ;(036) SPOOL TABLE
GT FTRTTR!FTHPQ!FTHIBW,I,JBTRTD##,ITMRTD## ;(037) REAL TIME
GT FTTLIM,J,JBTLIM## ;(040) CORE AND TIME LIMITS
EXP ZERO ;(041) UNUSED (FORMERLY QUEUE HEADERS)
EXP ZERO ;(042) UNUSED (FORMERLY JOBS IN QUEUES)
GT FTSET,I,COMTB2##,COMMX2## ;(043) SET COMMANDS
GT 1,I,APRSTS##,LENSTS## ;(044) CRASH TABLE
GT FTSWAP,I,ISCAN##,ISTMXL## ;(045) SWAP-IN LIST
GT FTSWAP,I,OSCAN##,OSTMXL## ;(046) SWAP-OUT LIST
GT FTSWAP,I,SSCAN##,SSTMXL## ;(047) SCHEDULER LIST
GT FTRSP,J,JBTRSP## ;(050) TIME USER BEGAN TO WAIT
GT 1,I,SYSTBL##,SYSMXL## ;(051) SYSTEM WIDE DATA
GT FTWHY,I,CRSHAC##,17000 ;(052) WHY RELOAD COMMENT
GT FTRSP,J,JBTRQT## ;(053) TIME IN RUN QUEUES
GT FTMS,I,JBTSPS##,ITMSPS## ;(054) SECOND CPU STATUS
;CONTINUED ON NEXT PAGE
GT 1,I,.C0CDB##,ITMC0C## ;(055) CPU0 CDB CONSTANTS
GT 1,I,.C0VBG##,ITMC0V## ;(056) CPU0 CDB VARIABLES
GT 1,I,.C1CDB##,ITMC1C## ;(057)
GT 1,I,.C1VBG##,ITMC1V## ;(060)
GT 1,I,.C2CDB##,ITMC2C## ;(061)
GT 1,I,.C2VBG##,ITMC2V## ;(062)
GT 1,I,.C3CDB##,ITMC3C## ;(063)
GT 1,I,.C3VBG##,ITMC3V## ;(064)
GT 1,I,.C4CDB##,ITMC4C## ;(065)
GT 1,I,.C4VBG##,ITMC4V## ;(066)
GT 1,I,.C5CDB##,ITMC5C## ;(067)
GT 1,I,.C5VBG##,ITMC5V## ;(070)
GT 1,I,FETTBL,FETMXL ;(071) FEATURE TABLE
GT FTDISK,I,SDVTBL##,SDVMXL## ;(072) ERSATZ DEVICE NAMES
GT FTRSP,I,.GTSCN##,SCNMXL## ;(073) SCNSER DATA
GT FTTALK,I,SNDTMP##,SNDMXL## ;(074) LAST SEND ALL
GT 1,I,TTCWDT##,TTCMXL## ;(075) SET TTY NAMES*
GT FTIPCF,I,PIDTAB##,MIDMXL## ;(076) PROCESS ID TABLE
GT FTIPCF,I,IPCTAB##,IPCMXL## ;(077) IPCF MISC. DATA
IFN FTKA10,<
EXP ZERO ;(100)NOT IN KA10
>
IFN FTKL10!FTKI10,<
GT 1,S,JBTUPM## ;(100)POINTER TO USER PAGE MAP
>
GT FTWATCH,I,WATTAB##,WTCMXL## ;(101) WATCH COMMANDS*
GT FTVM,P,.PDCVL## ;(102) CURRENT VM LIMITS
GT FTVM,P,.PDMVL## ;(103) MAX VM LIMITS
GT FTIPCF,P,.PDIPA## ;(104) IPCF STATISTICS
GT FTIPCF,P,.PDIPC## ;(105) IPCF POINTERS
GT FTIPCF,P,.PDIPI## ;(106) THIS JOB'S [SYSTEM]INFO
GT FTIPCF,P,.PDIPQ## ;(107) FLAGS AND QUOTAS
GT FTHSLN,P,.PDDVL## ;(110) POINTER TO DEVICE LOG NAME TABLE
GT FTKI10!FTKL10,P,.PDABS## ;(111) ADDRESS BREAK SETTING
EXP ZERO ;(112) RESERVED
GT FTVM,I,.GTVM##,GTVMXL## ;(113) VM DATA
GT FTVM,J,JBTVRT## ;(114) PAGING RATES
GT 1,I,.GTSST##,SSDMXL## ;(115) SCHEDULER STATISTICS
EXP ZERO ;(116) OBSOLETE
GT 1,J,JBTST2## ;(117)SECOND JOB STATUS WORD
GT FTNSCH,J,JBTSCD## ;(120) TYPES AND CLASS WORD
GT FTNSCH,I,CLSSTS##,CLSMXL## ;(121) QUOTAS BY CLASS
GT FTNSCH,I,CLSQTA##,CLSMXL## ;(122) SECONDARY QUOTAS BY CLASS
GT FTNSCH,I,CLSRTM##,CLSMXL## ;(123) RUNTIME BY CLASS SINCE STARTUP
EXP ZERO ;(124) UNUSED (FORMERLY SUBQUEUE HEADERS)
EXP ZERO ;(125) UNUSED (FORMERLY SUB QUEUE WORD FOR JOB )
;CONTINUED ON NEXT PAGE
GT FTIPCF,I,.GTSID##,SIDMXL## ;(126) SPECIAL PIDS
GT FTEQDQ,I,.EQTAB##,ENQMXL## ;(127) ENQ/DEQ STATISTICS
GT 1,J,JBTJLT## ;(130) JOB LOGIN TIME
GT FTKL10&FTEMRT,P,.PDEBT## ;(131) # JIFFIES OF EBOX TIME FOR JOB
GT FTKL10&FTEMRT,P,.PDEB2## ;(132) REMAINDER MOD RTUPS OF JIFFIES OF EBOX TIME FOR JOB
GT FTKL10&FTEMRT,P,.PDMBT## ;(133) # JIFFIES SPENT DOING MEMORY REFERENCES FOR JOB
GT FTKL10&FTEMRT,P,.PDMB2## ;(134) REMAINDER MOD RTUPS OF A MBOX JIFFIES FOR JOB
GT FTFDAE,P,.PDSTR## ;(135) DEVICE PROGRAM WAS RUN FROM
GT FTFDAE,P,.PDDIR## ;(136) DIRECTORY PROGRAM WAS RUN FROM
GT FTFDAE,P,.PDNAM## ;(137) PROGRAM NAME
GT FTSET,P,.PDDFL## ;(140) USER'S DEFAULTS
GT FTNET&FTCMSR,I,NETGTT##,.NTMXL## ;(141) NETSER PERFORMANCE MEASUREMENTS
GT FTPSCD,I,SCDPER##,%PERLN## ;(142) PERFORMANCE TABLE
GT FTVM&FTACCT&FTKCT,P,.PDVKC## ;(143)JOB'S VIRTUAL KCT
GT FTACCT,P,.PDUUC## ;(144)JOB'S UUO COUNT
;INSERT NEW TABLES ABOVE HERE
GTTBLN=.-NUMTAB ;LENGTH OF TABLE
IFN FTPATT,<
Z ;FOR PATCHING
Z
>
ZERO: 0 ;IN LOWSEG FOR SPY'ERS
$HIGH ;BACK TO THE HIGH SEGMENT
> ;END FTGETTAB CONDITIONAL
IFE FTGETTAB,<GETTAB=CPOPJ##>
MINTBB: MINTAB
DEFINE FTBITS(FET),<
.X==0
.Y==0
.Z==0
IRP FET<
IFGE .Y-21,<PRINTX ? FET CANT BE INSERTED>
IFN FT'FET,<.X==.X!1_.Y>
.Z==.Z!1_.Y
F.'FET==1_.Y
.Y==.Y+1>
XWD .Z,.X>
FT1==-1 ;FORCE ON (NAME=1)
FT0==0 ;FORCE OFF (NAME=0)
;TABLE OF BITS FOR MONITOR FEATURES
;ALWAYS ADD NEW FEATURES AT END OF LIST
;AND ATTEMPT TO INCLUDE IN MOST APPROPRIATE LIST
$LOW
FETTBL:
;(0) LIST OF MONITOR NON-I/O FEATURES WHICH DIRECTLY IMPACT CUSPS
FTBITS<2REL,GETTAB,DAEMON,PRV,SPL,JCON,POKE,PEEK,PTYUUO,CCIN,IPCF,PI,GALAXY,EQDQ,MIC,MLOG,MDA>
;(1) REAL-TIME AND SCHEDULING FEATURES
FTBITS<HPQ,HIBWAK,SLEEP,RTTRAP,TRPSET,LOCK,RTC,SHFL,SWAP,VM,NSCHED,PSCD,CMSR>
;(2) COMMAND FEATURES
FTBITS<ATTACH,TALK,EXAM,REAS,FINI,WATCH,SEDA,BCOM,VERS,SET,QCOM,CCLX,CCL,MONL,MOFF,EXE,PJOB>
;(3) ACCOUNTING FEATURES
FTBITS<TIME,KCT,UNAME,CNO,TLIM,FDAE,EMRT,ACCT>
;(4) NON I/O FEATURES NOT RELATED TO DEBUGGING
FTBITS<MEMP,MS,EL,2SWP,BOOT,KII,1,METR,KI10,PDBS,22BI,KA10,KL10,MEMN>
;(5) NON I/O DEBUGGING FEATURES
FTBITS<CHECK,MONP,RCHK,HALT,TRAC,PATT,WHY,RSP,2SEG>
;(6) DISK UUO FEATURES (THIS WORD IS FULL)
FTBITS<MOUN,SFD,PHYO,5UUO,STR,DQTA,DSUP,DSEK,DRDR,GSRC,AIR,APLB,DPRI,LIB,NUL,DSIM,DHIA>
;(7) DISK "INVISIBLE" FEATURES (THIS WORD IS FULL)
FTBITS<DOPT,DBAD,DHNG,DSTT,DALC,DSMC,DMRB,DETS,DUFC,DBBK,SWPE,FFRE,DISK,LOGIN,CBDB,2ATB,SLCK>
;(10) SCANNER, RP04 FEATURES
FTBITS<HDPX,GPO2,630H,MODM,SCNR,SCLC,DIAL,TPAG,TBLK,CAFE,2741,TYPE,TVP,D10H,RDX,RP04>
;(11) OTHER PERIPHERALS (THIS WORD IS FULL)
FTBITS<TMP,MTSE,CDRS,OPRE,LPTR,NET,CTY1,CRTR,CPTR,HSLN,MSGS,XTC,DAS7,TSK,TLAB,TAPOP,RDBA>
;(12) OTHER PERIPERALS (SECOND WORD)
FTBITS<DX10>
;(13) DISK "INVISIBLE" FEATURES (SECOND WORD)
FTBITS<DUAL>
;(14) DISK UUO FEATURES (SECOND WORD)
FTBITS<PSTR>
FETMXL=<.-FETTBL-1>B26
$HIGH
SUBTTL SETNAM & CNGPPN UUO'S
;UUO TO SET CURRENT PROGRAM NAME
; MOVE AC,[SIXBIT /NAME/]
; ALWAYS RETURN
SETNAM: MOVEM T1,JBTPRG##(J) ;STORE PROGRAM NAME FOR SYSTAT AND SYSDPY
IFN FTTLIM, < MOVSI T2,(JB.LSY) ;CLEAR "GOT FROM SYS:" FLAG
ANDCAM T2,JBTLIM##(J) ; INDICATES LOADER IS DONE
>
MOVSI T2,JACCT ;ALWAYS CLEAR JACCT
ANDCAM T2,JBTSTS##(J)
MOVEI T2,JS.RUU!JS.XO!JS.XOR ;CLEAR EXECUTE ONLY SO CAN SAVE
IFN FTKI10!FTKL10,<
MOVE T3,JBTSGN##(J) ;HI SEG CHARACTERISTICS FOR THIS JOB
MOVE T4,JOBPD1##(R) ;UUO PC
TLNE T3,GTSSEG ;HE SEG CONCEALED?
TLNN T4,(IC.LIP) ;UUO DONE FROM A PUBLIC PAGE?
>
ANDCAM T2,JBTSTS##(J) ; A PROGRAM LOADED BY XO LOADER
; ALWAYS CLEAR JACCT WITH JS.XO
IFN FTVM,<
MOVSI T2,(UP.GET) ;CLEAR GET IN PROGRESS FLAG
ANDCAM T2,.UPMP+.UPBTS
>
IFN FTKI10!FTKL10,<
PUSHJ P,MAPHGH## ;REDO THE MAP IN CASE CONCEALED
MOVE T1,JBTPRG##(J) ;RESTORE NAME
>
IFN FTWATCH&FTVERSION,<
JUMPE T1,CPOPJ## ;IF TO 0, DONT TYPE OUT
PUSHJ P,VERWAT## ;SEE IF WATCHING (IF SO, ONLY ON CPU0)
POPJ P, ;NO--JUST RETURN
PUSHJ P,INLMES## ;TYPE:
ASCIZ /:/
PUSHJ P,VERBTH## ;TYPE NAME AND VERSION
PJRST PRRBKC## ;TYPE RIGHT BRACKET <CRLF>
>
IFE FTWATCH&FTVERSION,<
POPJ P,
>
;UUO TO CHANGE PROJECT, PROGRAMMER NUMBER, FOR LOGIN ONLY
; MOVE AC,NEW PPN
; CALLI AC,CHGPPN
; NOT IMPLEMENTED
; OK
IFN FTLOGIN,<
CHGPPN: MOVSI T2,JLOG ;LOGGED IN BIT
TDNE T2,JBTSTS##(J) ;SKIP IF JOB NOT LOGGED IN
POPJ P, ;NO GOOD IF IT IS
MOVEM T1,JBTPPN##(J) ;OK, CHANGE PPN
JRST CPOPJ1## ;AND GIVE OK RETURN
> ;END CONDITIONAL ON FTLOGIN
IFE FTLOGIN,<CHGPPN==CPOPJ##>
SUBTTL DEVNAM UUO
IFN FT5UUO,<
;DEVNAM UUO (CALLI 64)
;OPERATES IN TWO MODES:
;MODE 1:C(AC) HAVE AN INIT'ED CHANNEL NUMBER
;DEVNAM RETURNS SIXBIT DEVICE NAME IN DEVNAM IN AC
;MODE 2: C(AC) ASSUMED TO HAVE SIXBIT LOGICAL DEVICE NAME
;IF ARE GREATER THAN 17. PHYSICAL NAME RETURNED IN AC.
UDEVNM: PUSHJ P,DVCNSG ;SEARCH FOR CHANNEL OR DEVICE
JRST RTZER ;NONE--RETURN ERROR AS 0
IFN FTDISK,<
TLZ F,-1
CAIE F,DSKDDB## ;T1 IS MORE SPECIFIC THAN 'DSK'
>
MOVE T1,DEVNAM(F) ;GET PHYSICAL NAME
JRST STOTC1## ;PUT IN AC AND RETURN
> ;END CONDITIONAL ON FT5UUO
IFE FT5UUO,<
UDEVNM==CPOPJ##
>
SUBTTL REAL-TIME AND HIBWAKE FEATURE
;UUO TO SET JOB TO USE IO IN USER MODE
;AND TO SET PI INTERRUPT LOCATION IN LOWER CORE(WORKS ONLY ON P-10'S -SEE NEXT PAGE)
;CALL: CALL AC,[SIXBIT /TRPSET/]
; ERROR RETURN, USER NOT ALLOWED TO DO IO IN USER MODE
; OK RETURN
;WHERE RH(AC)=REL ADR. OF 1 INSTRUCTION TO BE MOVED INTO
;THE MONITOR PI TRAP LOCATION(40-57) AS SPECIFIED BY LH(AC)
;RELOCATION OF JOB IS ADDED TO RH OF INSTRUCTION AS IT IS MOVED.
;ALSO THE RELOCATION IS ADDED TO THE RH OF WORD IN USER AREA SPECIFIED BY
;RH OF USER INSTRUCTION IN CASE IT IS A BLKO/BLKI POINTER
;THE USER MUST RESET EVERY TRPSET CALL IF BLKI/BLKO POINTER
;AND SHOULD SET RH TO 0 IF JSR PC WORD
;THE APR IS ALSO SET SO USER MAY DO IO IN USER MODE
;TO SET USER MODE IO WITHOUT SETTING LOWER CORE, C(AC)=0
;STOP TIME SHARING ONLY IF AC IS NON-ZERO(IE RUN ONLY JOB 1)
IFN FTTRPSET,<
TRPSET::
IFE FTPRV,<
CAIE J,1 ;IS THIS JOB 1 (REQUIRED IF NO PRIVILEG BITS)
POPJ P, ;NO. ERROR RETURN
>
IFN FTPRV,< MOVE T2,JBTPRV##(J) ;IS JOB PRIVILEGED TO DO TRPSET UUO?
TLNN T2,PVTRPS ;PVTRPS IS SPECIFIED IN ACCT.SYS AND SETUP BY LOGIN
POPJ P, ;NO, ERROR RETURN
>
MOVEI P4,.C0CDB## ;ASSUME JOB IS ON CPU0
SETZM .CPSTS##(P4) ;CLEAR THE STOP TIME SHARING FLAG
IFE FTMS<
JUMPE T1,TRPST1 ;IS AC 0?(DO NOT SET PI LOC IF YES)>
IFN FTMS<JUMPE T1,TRPST0>
HLRZ T2,T1 ;NO, SET LOWER CORE
CAIL T2,40 ;IS IT LEGAL LOWER CORE ADR.?
CAIL T2,60
POPJ P, ;NO, ERROR RETURN
IFN FTKI10!FTKL10,<
IFN FTLOCK,<
PUSHJ P,LOKEVC## ;IF KI10, JOB MUST BE LOCKED IN EVM
; IS IT?
>
POPJ P, ;NO, ERROR RETURN
>
IFN FTMS,< ;DUAL CPU FEATURE?
TRPST0: PUSHJ P,CPUTRP## ;GO SEE IF USER CAN DO TRPSET UUO ON DUAL CPU
POPJ P, ;ERROR RETURN, SET TO RUN ON CPU1 ONLY
; BUT NOT LOCKED IN CORE
;SET TO RUN ON CPU0 OR CPU1, T4=CDB
; FOR CPU HE IS ALLOWED TO RUN ON
>
IFN FTMS!FTKI10!FTKL10,<
PUSHJ P,GETTAC## ;RESTORE USER'S AC ARGUMENT TO T1
JUMPE T1,TRPST1
>
MOVEM J,.CPSTS##(P4) ;SET STOP TIME SHARING FLAG, SO NO OTHER JOBS
; JOBS WILL RUN AND NO CORE SHUFFLING
HRLI T1,R ;YES, SET TO RELOCATE
MOVE T1,@T1 ;GET THE INSTR.
ADDI T1,(R) ;ADD RELOCATION SO WILL POINTER TO USER AREA
HRRZ U,R ;USER RELOCATION
ADDM U,(T1) ;ALSO ADD RELOCATION TO WORD POINTED TO BY INSTR
; IN CASE IT IS A BLKI/BLKO POINTER WORD
; USER SHOULD RESET RH OF POINTER IF BLKI/BLKO INSTR
; OR CLEAR PC LOC IF JSR INSTR
ADD T2,.CPTOS##(P4) ;ADD IN TRAP OFFSET VALUE FOR THIS CPU
EXCH T1,(T2) ;AND STORE IN MONITOR TRAP LOC.
TRPST1: AOS (P) ;OK RETURN
MOVSI T2,(XC.UIO) ;SET USER IO PC FLAG
IORM T2,JOBPD1##(R) ;IN UUO RETURN PC
JRST STOTAC## ;RETURN PREVIOUS CONTENTS OF PI LOC.
> ;END CONDITIONAL ON FTTRPSET
IFE FTTRPSET,<
TRPSET==:CPOPJ##
>
;ROUTINE TO DISMISS INTERRUPT FOR JOB DOING USER IO
;WHEN PC IS IN EXEC MODE
;NOTE THE TRPJEN UUO HAS BEEN ELIMINATED
;BECAUSE UUO HANDLER CANNOT BE INTERRUPTED AND REENTERED
;INSTEAD INTERRUPTS IN USER MODE ARE DISMISSED
;BY USING OP CODE 100 (UJEN) WHICH
;TRAPS TO EXEC 61 INSTEAD OF 41 ON P-10'S
;UJEN IS A NO-OP ON P-6'S AND SO THIS FACILTY IS GOOD ON P-10'S ONLY
;CALL: RESTORE ALL EXEC ACS
; UJEN ADR ;UJEN=100
; WHERE ADR CONTAINS PC STORED BY INTERRUPT JSR
; SEE UUO HANDLER (UUO2) FOR CODE
;RTTRP UUO
;LOCK UUO
;HPQ UUO
; HIBERNATE/WAKE UUOS
;SIGN BIT OF UUO AC ARG=1 IF JOB
; WANT TO BE SWAPPED OUT IMMEDIATELY
IFN FTHIBWAK,<
HIBUUO:
IFE FTVM,<
AOS JOBPD1##(R) ;GIVE SKIP RETURN
>
IFN FTVM,<
PUSHJ P,INCPD1##
>
IFN FTPI,<
XCT NOPISK## ;SKIP IF USER NOT ENABLED FOR TRAPS
SKIPL JBTPIA##(J) ;GET ADDRESS OF PI TABLE
JRST HIBER ;NOT ENABLED
MOVSI T2,(JFCL) ;ARE WE WAITING FOR A UUO TO HAPPEN
CAME T2,@JBTPIA##(J) ; ..
POPJ P, ;YES--THIS WAS THE UUO
>
HIBER:: MOVSI T2,(JS.HIB) ;SET HIBER BIT
IORM T2,JBTST2##(J)
PUSHJ P,HIBER4 ;DO THE UUO
JFCL
MOVSI T2,(JS.HIB) ;CLEAR HIBER BIT
ANDCAM T2,JBTST2##(J)
POPJ P,
HIBER4: PUSHJ P,SAVE1## ;SAVE P1
HLRZ T2,T1 ;GET THE PROTECTION BITS
DPB T2,HIBPRT## ;STORE PROTECTION CODE IN LEFT HALF OF JBTRTD(J)
IFN FTIPCF,<
MOVSI T3,IPCACE## ;CLEAR IPC ACTIVITY ENABLE
ANDCAM T3,JBTRTD##(J)
TRNE T2,IPCUUB## ;USER WANT IPC ACTIVITY?
IORM T3,JBTRTD##(J) ;YES, DO SO
>
MOVSI P1,TTILCE## ;TTY CHARACTER OR LINE MODE BIT
TDNE P1,JBTRTD##(J) ;IS JOB GOING INTO CHARACTER MODE?
PUSHJ P,HIBTTY## ;YES, GO SET UP LINE CHARACTERISTICS
MOVSI T2,WAKEB## ;CHECK IF JOB HAS BEEN AWAKENED
MOVEI P1,SLPQ## ;PREPARE TO PUT JOB IN SLEEP QUEUE
CONO PI,PIOFF## ;GUARD AGAINST WAKEUP AT INTERRUPT LEVEL
TDNN T2,JBTRTD##(J) ;HAS THIS JOB BEEN WOKEN
JRST HIBER1 ;NO, THEN PUT IT TO SLEEP
ANDCAM T2,JBTRTD##(J) ;CLEAR THE WAKE BIT
CONO PI,PION## ;RESTORE THE PI STATUS
JRST CPOPJ1## ;GIVE A SKIP RETURN TO THE USER
HIBER1: DPB P1,PJBSTS## ;STORE THE SLEEP CODE IN JBTSTS WORD
CONO PI,PION## ;RESTORE PI SYSTEM
IFN FTSWAP,<
JUMPGE T1,HIBER2 ;DOES JOB WANT TO BE SWAPPED OUT IMMEDIATELY?
; (HBRSWP SET)
PUSHJ P,ZERIPT## ;YES, MARK HIM AS SWAPPABLE.
PUSHJ P,GETWDU## ;PICKUP. ARGUMENT OF UUO AGAIN
>
;MORE
HIBER2: AOS (P) ;GIVE SKIP RETURN WHEN JOB WAKES UP
HRRZS T1 ;GET THE SLEEP TIME IN MILLISEC
JUMPE T1,HIBER3 ;IF NO SLEEP TIME, DONT ENTER CLOCK REQUEST
IMUL T1,TICSEC## ;CONVERT TO JIFFIES
IDIVI T1,^D1000 ; FROM MILLISECONDS
SKIPE T2 ;IS THIS AN EVEN NUMBER OF JIFFIES
AOS T1 ;NO, ALWAYS ROUND UP TO NEXT JIFFY
CAILE T1,7777 ;WAS THIS A VERY LARGE NUMBER
MOVEI T1,7777 ;YES, THEN SLEEP THE MAXIMUM TIME
JRST MSLEEP ;GO ENTER SLEEP TIME IN CLOCK REQUEST QUEUE
IFN FTSWAP,<
HIBER3: PUSHJ P,FNPDBS## ;GET THE PDB ADDRESS
PUSHJ P,CLRIPT## ;CLEAR IN-CORE PROTECT TIME
PJRST WSCHED## ;GO RESCHEDULE>
IFE FTSWAP,<HIBER3==WSCHED##>
;HERE ON A WAKE UUO
WAKUUO:
;HERE FROM RTTRP AT INTERRUPT LEVEL
WAKEUP::JUMPLE T1,WAKEME ;WAKE UP CURRENT JOB ON NEG ARGUMENT
PUSHJ P,LGLPR1## ;IS THIS AN UNREASONABLE REQUEST?
POPJ P, ;YES, GIVE AN ERROR RETURN
IFN FTLOGI,< PUSHJ P,PRVJ## ;DOES THIS JOB HAVE SPECIAL PRIVELEGES?
JRST WAKOK1 ;YES, WAKE THE JOB UP ALWAYS
>
EXCH T1,J ;SET UP TO TAKE THE JOB OUT OF SLPQ
LDB T2,HIBPRT## ;GET PROTECTION CODE
TRNE T2,4 ;ONLY-ME PROTECTION?
JRST ONLYME ;YES, MAKE SURE THIS IS RIGHT JOB
IFN FTLOGIN,<
TRNE T2,1 ;ALL PROJECTS OK?
JSP T3,CHPRJ ;NO, CHECK THIS PROJECT NUMBER
TRNE T2,2 ;ALL PROGRAMMERS OK?
JSP T3,CHPRG ;NO, CHECK THIS PROGRAMMER NUMBER
> ;END FTLOGIN
JRST WAKEOK ;GO WAKE THE JOB UP
WAKEME: SKIPA T1,J
WAKOK1: EXCH J,T1 ;SET UP J PROPERLY
WAKEOK:
MOVSI T2,(JS.HIB) ;JOB DID SLEEP UUO BIT
TDNN T2,JBTST2(J) ;SLEEP OR HIBER?
JRST SETWAK ;SLEEP, JUST SET WAKE BIT
IFN FTPI,<
XCT OKSGNL## ;JOB SET UP FOR INTERRUPTS?
JRST WAKEIT ;NO
MOVE T2,JBTPIA##(J)
MOVEM T1,PITWJB##(T2) ;YES, SAVE JOB NUMBER
MOVE T3,T1
SIGNAL C$WAKE ;SIGNAL WAKEUP
EXCTUU <MOVEM T3,IBKISW##(M)>
>
WAKEIT:
MOVEI T1,RNQ## ;PREPARE TO PUT JOB IN THE RUN QUEUE
CONO PI,PIOFF## ;GUARD AGAINST HIGHER PI ACTIVITY
LDB T2,PJBSTS## ;GET CURRENT QUEUE CODE
CAIE T2,SLPQ## ;IS THE JOB IN THE SLEEP QUEUE
JRST NOTSLP ;NO, THEN DONT WAKE THE JOB UP
IFN FTPSCD,<
AOS REQWK## ;COUNT A WAKE
>
WAKOKE::DPB T1,PJBSTS## ;PUT THE JOB IN THE RUN QUEUE
CONO PI,PION## ;TURN THE PI BACK ON
PUSHJ P,SETR2## ;SET A SCHEDULER REQUEST
WAKOKA:
IFN FTHPQ,<
LDB T1,HPQPNT## ;GET CURRENT RUNQUE
JUMPE T1,CPOPJ1## ;IF IT IS TS QUEUE THEN DONT SCHEDULE
MOVSI T2,SWP ;PREPARE TO CHECK IF JOB IS ON DISK
CONO PI,PIOFF## ;GUARD AGAINST HIGH PI WAKE UP
SETOM .C0CKF## ;FLAG THE SCHEDULER FOR CPU0
SKIPN .C0RTF## ;IS THERE A FORCED SCHEDULE TO BE DONE
SETOM .C0RTF## ;NO, MARK ONE IS IN PROGRESS FOR CPU0
TDNN T2,JBTSTS##(J) ;IS THIS JOB SWAPPED OUT
JRST WAKOK3 ;NO. PROCEED.
SKIPG T2,.C0RTF## ;ANYONE IN .C0RTF?
JRST WAKOK2 ;NO. PUT OUR NUMBER IN IT.
LDB T3,HPQPT2## ;YES. GET HIS HPQ NUMBER
CAMLE T1,T3 ;IS HE AHEAD OF US?
WAKOK2: HRRZM J,.C0RTF ;NO. PUT OUR NUMBER IN.
WAKOK3: CONO PI,PICLK## ;CAUSE AN INTERRUPT ON PI 7
>
JRST CPOPJ1## ;GIVE SKIP RETURN
;WAKJOB IS A ROUTINE WHICH CAN BE CALLED FROM ANY INTERRUPT LEVEL
;TO WAKE UP A HIBERNATING JOB. THE CALLING SEQUENCE IS:
; MOVE T1,JOBNUM ;T1 = # OF JOB TO BE WOKEN
; PUSHJ P,WAKJOB ;WAKE UP JOB
; RETURN ALWAYS
;WAKJOB SAVES ALL ACS EXCEPT T1, T2
WAKJOB::PUSH P,J ;SAVE J
MOVE J,T1
PUSHJ P,WAKEIT ;GO WAKE JOB
PJRST JPOPJ## ;ALWAYS SKIP RETURNS
PJRST JPOPJ## ;RESTORE J AND RETURN
;WAKEJB SAME AS WAKJOB EXCEPT J=JOB#
WAKEJB::PUSHJ P,WAKEIT
POPJ P,
POPJ P,
;WAKPST IS A ROUTINE TO EITHER WAKE A HIBERNATING
; JOB OR POST THE WAKE IF JOB IS SLEEPING/RUNNING
; T1=JOB NUMBER
;CLOBBERS T2
WAKPST::MOVSI T2,(JS.HIB) ;JOB SLEEPING
TDNE T2,JBTST2##(T1) ; OR HIBERNATING
PJRST WAKJOB ;HIBER, START IT UP NOW
PUSH P,J ;SAVE J
MOVE J,T1 ;SET JOB NUMBER
PUSHJ P,SETWAK ;POST THE WAKEUP
PJRST JPOPJ##
PJRST JPOPJ## ;ALWAYS NON-SKIP RETURN
NOTSLP: CAIE T2,NAPQ## ;NOT SLEEP, IS IT A NAP?
JRST NOTNAP ;NO, SET WAKE BIT
DPB T1,PJBSTS## ;ITS A NAP, CLEAR WAIT STATE
CONO PI,PION## ;TURN ON PIS AGAIN
JRST WAKOKA ;AND RETURN AFTER CHECKING FOR HPQ STUFF
SETWAK: CONO PI,PIOFF## ;GUARD AGAINST PI LEVEL ACTIVITY
NOTNAP: MOVSI T2,WAKEB## ;SET WAKEUP BIT INSTEAD
IORM T2,JBTRTD##(J) ;SET WAKE UP BIT
CONO PI,PION## ;DONT RESCHEDULE
JRST CPOPJ1## ;SKIP RETURN TO CALLER
ONLYME: CAME T1,J ;IS THIS JOB ME
POPJ P, ;NO, GIVE ERROR RETURN
JRST WAKEOK ;YES, GO WAKE THE JOB UP
IFN FTLOGIN,<CHPRJ: HLLZ T4,JBTPPN##(T1) ;GET OBJECT JOB'S PROJECT NUMBER
XOR T4,JBTPPN##(J) ;COMPARE WITH THIS JOB'S PROJECT
MOVSS T4 ;RESULT TO RH
JRST CHPRG1 ;TEST
CHPRG: HRRZ T4,JBTPPN##(T1) ;GET OBJECT JOB'S PROGRAMMER NUMBER
XOR T4,JBTPPN##(J) ;COMPARE WITH THIS JOB'S PROGRAMMER
CHPRG1: TRNE T4,-1 ;SKIP IF EXACT MATCH
POPJ P, ;NO, GIVE ERROR RETURN
JRST (T3) ;OK, KEEP GOING
> ;END FTLOGIN
> ;END FTHIBWAK
IFE FTHIBWAK,<HIBER:
WAKUUO::
WAKJOB::
WAKEUP::POPJ P,
>
SUBTTL DAEMON UUO'S AND ROUTINES
IFN FTDAEM,<
;UUO TO REQUEST SERVICE BY DAEMON
;CALL MOVE AC,[XWD +LENGTH,ADDR OF ARG LIST]
; (FIRST ARG = FUNCTION CODE--SEE DAEMON FOR LEGAL FUNCTIONS)
; CALLI AC,102
; ERROR RETURN
; OKAY RETURN
CALDAE: PUSH P,T1 ;SAVE USER ARG AC
PUSHJ P,STDAEM## ;IS DAEMON RUNNING?
JRST TPOPJ## ;NO, ERROR RETURN TO USER-HIS AC UNCHANGED
POP P,T2 ;T2=USER'S AC
HRR M,T2 ;ADR. OF FIRST ARG IN USER AREA
PUSHJ P,GETWDU## ;GET FIRST WORD = FUNCTION
; LEAVE IN T1 FOR DAEMON TO FINE IN DUMP ACS.
MOVEI T3,JDCQ## ;MAKE JOB UNRUNABLE
DPB T3,PJBSTS## ;BY PUTTING IT IN DAEMON WAIT STATE
PUSHJ P,WSCHED## ;CALL SCHEDULER
;DAEMON WILL FIND T1 IN DUMP ACS FOR FUNCTION
; IT WILL RETURN ERROR CODE IN FUMP T1 AND 0/NON-0
; FLAG IN T1+1 IF SKIP/NON-SKIP RETURN
JUMPE T2,STOTC1## ;SKIP RETURN IF OK
JRST STOTAC## ;ERROR RETURN - STORE RETURN IN AC IN ANY CASE
;STILL IN FTDAEM CONDITIONAL
;UUO TO READ OR WRITE ANOTHER JOB'S CORE
;CALL MOVEI AC,ADDR OF 2 WORD ARGUMENT LIST
; CALLI AC,JOBPEK
; ERROR RETURN
; OK RETURN
;FIRST ARG LH=FLAGS AND JOB NUMBER
;BIT 0=0 IF READ, 1 IF WRITE
;RH=NUMBER OF WORDS TO TRANSFER
;SECOND ARG=XWD SOURCE ADDR, DESTINATION ADDR
JOBPEK: PUSHJ P,SAVE4## ;SAVE P1-P4
PUSHJ P,PRUSET ;REQUIRES PRIVILEGES
POPJ P, ;NOT PRIVILEGED
HLRZ P1,T1 ;RH P1=JOB NUMBER
TRZ P1,600000 ;CLEAR FLAGS
HLL P1,T1 ;LH P1=FLAGS
HRRZ P2,T1 ;P2=LENGTH OF TRANSFER
HRRZ T1,P1 ;T1=JOB NUMBER
PUSHJ P,LGLPRC## ;SKIP IF LEGAL JOB NUMBER
POPJ P, ;NO, REFUSE TO DO IT
NOSCHEDULE
IFN FTVM,<
MOVSI T2,SWP ;JOB ON ITS WAY OUT OR IN?
TDNE T2,JBTSTS##(T1) ;LOSE IF SO
JRST JOBPKX ;RETURN IF SWP=1
>
MOVM T2,FINISH## ;T2 = JOB IN TRANSIT
SKIPE JBTADR##(P1) ;SKIP IF JOB SWAPPED
CAIN T2,(P1) ;SKIP IF ALL IN CORE
JRST JOBPKX ;NOT IN CORE
CAILE P2,1000 ;SKIP IF UNDER MAX
MOVEI P2,1000
PUSHJ P,GETWD1## ;GET XWD SOURCE, DESTINATION
IFN FTVM,<
PUSH P,T1 ;SAVE T1
TLNE P1,400000 ;SKIP IF READ
HLRZS T1 ;ADDR IN USER'S JOB
HRRZS T2,T1 ;. .
ADDI T2,-1(P2) ;HIGHEST ADDRESS IN USER'S JOB
PUSHJ P,TRNGE## ;SEE IF PROCEEDING WILL CAUSE A PAGE FAULT
CAIE J,(P1) ;JOB PEK ON SELF?
JRST JOBPK2 ;NO, PROCEED
MOVE T1,(P) ;GET XWD BACK
TLNN P1,400000 ;SKIP IF WRITE
HLRZS T1 ;ADDR IN USER'S JOB
HRRZS T2,T1 ; ...
ADDI T2,-1(P2) ;HIGHEST ADDR IN JOB
PUSHJ P,TRNGE## ;CHECK IT
JOBPK2: POP P,T1 ;RESTORE XWD
>
;STILL IN FTDAEM CONDITIONAL
;HERE TO CHECK IF SOURCE ADDR IS FROM HIGH SEGMENT
MOVE P3,R ;P3=JBTADR FOR THIS JOB
MOVE T4,JBTADR##(P1) ;T4=JBTADR FOR USER'S JOB
TLNE P1,400000 ;SKIP IF READ, NOT IF WRITE
EXCH T4,P3 ;T4=SOURCE JBTADR, P3=DESTINATION JBTADR
HLRZ T3,T4 ;T3=SIZE OF SOURCE LOW SEGMENT
HLRZ T2,T1 ;T2=SOURCE ADDRESS
IFN FT2REL,<
CAMGE T2,T3 ;SKIP IF SOURCE ADDR GT LOW SEGMENT SIZE
JRST JOBPK1 ;SOURCE ADDRESS IS IN LOW SEGMENT
MOVE T4,JBTSGN##(P1) ;HIGH SEGMENT NUMBER FOR USER'S JOB
TLNE P1,400000 ;SKIP IF READ, NOT IF WRITE
MOVE T4,JBTSGN##(J) ;HIGH SEGMENT NUMBER FOR THIS JOB
JUMPE T4,JOBPKX ;EXIT IF SOURCE JOB HAS NO HIGH SEGMENT
CAIGE T3,400000 ;SKIP IF LOW SEGMENT GT 400000 LOCATIONS
MOVEI T3,400000 ;NO, T3=OFFSET FOR HIGH SEGMENT
IFN FTKI10!FTKL10,<
JUMPL T4,JOBPK0 ;GO IF A SPY SEG.
LDB T3,[POINT 9,JBTUPM##(T4),8] ;HIGH SEG ORIGIN PAGE #
LSH T3,P2WLSH## ;VIRTUAL ADDRESS OF HIGH SEG.
JOBPK0:>
SUB T2,T3 ;T2=ADDRESS IN SEGMENT FOR TRANSFER
JUMPL T2,JOBPKX ;ILLEGAL ADR IF NEGATIVE
HRL T1,T2 ;ADDRESS IN SEGMENT BACK TO ACTUAL ADDRESS
SKIPL T4 ;SKIP IF SPY SEG
SKIPA T4,JBTADR##(T4) ;T4=JBTADR FOR SOURCE SEGMENT
HRLZS T4 ;T4=XWD LENGTH, START ADDR OF SPYSEG
HLRZ T3,T4 ;T3=SIZE OF SOURCE SEGMENT
>
;HERE TO CHECK IF SOURCE ADDRESS FITS IN SOURCE SEGMENT
JOBPK1: SUBI P2,1 ;LENGTH OF TRANSFER -1
ADD T2,P2 ;SOURCE ADDR+LENGTH OF SEG=LAST ADDR OF SOURCE
CAMLE T2,T3 ;SKIP IF LE LAST ADDR OF SOURCE SEG
JRST JOBPKX ;DOESN'T FIT IN SOURCE SEGMENT
;HERE TO CHECK IF DESTINATION FITS IN DESTINATION SEGMENT
;NOTE THAT DESTINATION MUST BE A LOW SEGMENT - IF A HIGH SEGMENT IS
; SPECIFIED IT WILL BE OUT OF BOUNDS AND HENCE ILLEGAL. THIS IS IN LIEU
; OF DETERMINING APPROPRIATE PRIVILEGES TO WRITE IN HIGH SEGMENT
HRRZ T2,T1 ;T2=DESTINATION ADDRESS
ADD T2,P2 ;LAST ADDR OF DESTINATION
HLRZ T3,P3 ;T3=SIZE OF DESTINATION SEGMENT
CAMLE T2,T3 ;SKIP IF FITS IN DESTINATION SEGMENT
JRST JOBPKX
;HERE WHEN ADDRESSES ARE VERIFIED TO BE LEGAL
AOJE P2,JOBPX1 ;EXIT NOW IF 0 WORDS TO TRANSFER
PUSHJ P,JOBPKD## ;GO DO THE BLT
IFN FTVM,<
JRST JOBPKX ;LOSE (REFERENCE TO TARGET JOB WILL
; CAUSE A PAGE FAULT)
>
JOBPX1: SCHEDULE ;TURN ON SCHEDULING
JRST CPOPJ1##
JOBPKX: SCHEDULE
POPJ P,
;STILL IN FTDAEM CONDITIONAL
;UUO TO TAKE JOB OUT OF DAEMON QUEUE
;CALL MOVE AC,XWD +LENGTH, ADDR OF ARGUMENT LIST
; CALLI AC,DAEFIN
; ERROR RETURN
; OK RETURN
;FIRST ARG=JOB NUMBER
;REST OF ARGUMENTS=ACCOUNTING INFORMATION
DAEFIN: PUSHJ P,PRUSET ;SEE IF JOB IS PRIVILEGED
POPJ P,
PUSHJ P,LGLPRC## ;SEE IF JOB NUMBER LEGAL
POPJ P, ;NO, ERROR RETURN
EXCH J,T1 ;J=JOB DAEMON HAS FINISHED
PUSHJ P,DAEDON## ;START USER NOW THAT DAEMON IS DONE
JRST CPOPJ1## ;SKIP RETURN
> ;END CONDITIONAL ON FTDAEM
IFE FTDAEM,<
JOBPEK=CPOPJ##
CALDAE=CPOPJ##
DAEFIN=CPOPJ##
>
IFN FT5UUO,<
;UUO TO FORCE A COMMAND FOR A JOB
;CALL MOVE AC,XWD +LENGTH OR 0, ADDR OF ARG LIST
; CALLI AC,FRCUUO
; ERROR RETURN
; OK RETURN
; FIRST ARG=SIXBIT COMMAND TO FORCE
; SECOND ARG=JOB NUMBER OR THIS JOB IF NOT SPECIFIED
FRCUUO: PUSHJ P,PRUSET ;REQUIRES PRIVILEGES
POPJ P, ;NO GOOD
MOVSI T4,MTTFCM## ;MINUS LENGTH OF COMMAND TABLE
CAME T1,TTFCOM##(T4) ;SKIP IF FOUND COMMAND
AOBJN T4,.-1
JUMPGE T4,CPOPJ## ;NO GOOD IF NOT LEGAL COMMAND
MOVE T1,J ;T1=OUR JOB
CAIE T3,1 ;SKIP IF JOB NOT SPECIFIED
PUSHJ P,GETWD1## ;GET 2ND ARG=JOB NUMBER
SKIPN T1 ;SUBMITTED ZERO SECOND ARGUMENT?
MOVE T1,J ;YES, USE THIS JOB #
PUSHJ P,LGLPRC## ;SKIP IF LEGAL JOB NUMBER
POPJ P,
MOVSI T3,JNA ;DON'T ALLOW FORCED COMMAND IF NOT A JOB
TDNN T3,JBTSTS##(T1) ;JOB NUMBER ASSIGNED?
POPJ P, ;NO, LOSE
HRRZ F,TTYTAB##(T1) ;ADDRESS OF TTY DDB
HRRZ U,DDBLDB##(F) ;GET POINTER TO LDB
JUMPE U,CPOPJ## ;FAIL ON DETACHED JOB
HRRZ T2,T4 ;T2=INDEX OF COMMAND
PUSHJ P,COMFRC## ;FORCE COMMAND
JRST CPOPJ1## ;OK
POPJ P, ;CAN'T
> ;END CONDITIONAL FT5UUO
IFE FT5UUO,<
FRCUUO==CPOPJ##
>
IFN FT5UUO!FTDAEM,<
;SUBROUTINE TO CHECK FOR PRIVILEGES AND RETURN FIRST ARGUMENT
;CALL T1=CONTENTS OF USER'S AC=+LENGTH, ADDR
;RETURN T1=CONTENTS OF USER LOCATION ADDR
; T3=+LENGTH OF ARGUMENT LIST
PRUSET::
HRR M,T1 ;SOME CALLERS (EG CAL78.)
HLRZ T3,T1 ;USE LENGTH EVEN IF NOT PRIVILEGED.
PUSHJ P,GETWDU## ;GET FIRST ARGUMENT
IFE FTLOGIN,<
PJRST CPOPJ1## ;OBVIOUSLY CAN'T CHECK PRIVS
>;END IFE FTLOGIN
IFN FTLOGIN,<
PUSH P,T1 ;USER'S AC
PUSH P,T3 ;ARG LIST LENGTH
MOVSI T1,JP.POK ;NOW CHECK PRIVS
PUSHJ P,PRVBIT## ;SKIP RETURN IF NOT
AOS -2(P) ;FUDGE SKIP RETURN TO CALLER FOR PRIV OK
POP P,T3 ;BUT GIVE HIM THIS IN ANY CASE
PJRST TPOPJ##
>;END IFN FTLOGIN
> ;END CONDITIONAL ON FT5UUO!FTDAEM
IFN FTGALAXY,<
;UUO TO SET PARAMETERS ON SPOOLED FILES
;CALL: MOVE AC,[N,,E]
; SPPRM. AC,
; ERROR RETURN
; NORMAL RETURN
;
;E: CHANNEL # OR DEVICE NAME
; A SPOOLING PARAMETER BLOCK
;
;ERRORS: -1 = ADDRESS CHECK
; 0 = ARG BLOCK TOO SHORT
; 1 = NO SUCH DEVICE
; 2 = DEVICE NOT ASSIGNED OR INITED
; 3 = DEVICE NOT SPOOLED
; 4 = NO FREE CORE FOR SPB
SPPRM: PUSHJ P,SAVE1## ;SAVE AN AC
HRR M,T1 ;POINT AT ARGUMENT ADDRESS
HLRE P1,T1 ;GET LENGTH IN P1
CAIGE P1,2 ;ENOUGH THERE?
PJRST ECOD0## ;NO, ERROR
PUSHJ P,GETWRD ;GET DEVICE SPEC
PJRST RTM1
PUSHJ P,DVCNSG ;FIND THE DDB
PJRST ECOD1## ;NO SUCH DEVICE
MOVEI T1,ASSCON!ASSPRG ;GET ASSIGNED + INITED BITS
TDNN T1,DEVMOD(F) ;IS DDB EITHER
PJRST ECOD2## ;NOPE
SKIPL DEVSPL(F) ;SPOOLED?
PJRST ECOD3## ;NO, LOSE
HRRZ T1,DEVSPM##(F) ;IS THERE A SPOOL PARAM BLOCK?
JUMPN T1,SPPRM1 ;YES, USE IT
MOVEI T2,SPBCOR## ;HOW MUCH CORE WE NEED
PUSHJ P,GET4WD## ;GET THAT CORE
PJRST ECOD4## ;NO FREE CORE
HRRZM T1,DEVSPM##(F) ;REMEMBER WHERE IT IS
HRLZ T2,T1 ;GET ADR,,0
HRRI T2,1(T1) ;GET ADR,,ADR+1
SETZM 0(T1) ;CLEAR THE FIRST WORD
BLT T2,SPBMAX##-1(T1) ;CLEAR THE REST
SPPRM1: SUBI P1,1 ;ADJUST FOR DEVICE NAME
CAILE P1,SPBMAX## ;BIGGER THAN MAX
MOVEI P1,SPBMAX## ;YES, USE MAX
MOVNS P1 ;MAKE P1 NEGATIVE
HRLZS P1 ;MAKE IT A
HRR P1,T1 ; POINTER
SPPRM2: PUSHJ P,GETWR1## ;GET NEXT WORD
PJRST RTM1 ;ADDR CHECK
MOVEM T1,(P1) ;SAVE USERS ARG
AOBJN P1,SPPRM2 ;LOOP FOR ALL ARGS
PJRST CPOPJ1## ;GIVE GOOD RETURN
> ;END IFN GALAXY
SUBTTL ALLOC. UUO
IFN FTGALAXY,<
;UUO TO ALLOCATE/DEALLOCATE MOUNTABLE DEVICES
;CALL WITH:
; MOVE AC,[N,,E]
; ERROR RETURN
; NORMAL RETURN
;THIS IS A PRIVILEGED UUO WHICH MAY BE EXECUTED BY THE SYSTEM
; MOUNTABLE-DEVICE ALLOCATOR ONLY.
;FUNCTIONS AND ARGUMENTS
.ALLAD==1 ;FUNCTION 1 -- ALLOCATE DEVICE
; FUNCTION
; DEVICE
; JOB
.ALLFD==2 ;FUNCTION 2 -- FREE A DEVICE
; FUNCTION
; DEVICE
;DISPATCH TABLE
ALLDSP: EXP ERRIF ;ILLEGAL FUNCTION
EXP ALLF1 ;ALLOCATE DEVICE
EXP ALLF2 ;FREE A DEVICE
ALLMXF==.-<ALLDSP+1>
;STILL IN IFN FTGALAXY
;
;ERROR CODES
ALLIS%==1 ;(1) INSUFFICIENT PRIVS
ALLIF%==2 ;(2) ILLEGAL FUNCTIONS
ALLID%==3 ;(3) ILLEGAL DEVICE
ALLIJ%==4 ;(4) ILLEGAL JOB
ALLIA%==5 ;(5) ILLEGAL ARGLIST
;ERROR ROUTINES
ERCODE ERRIS,ALLIS%
ERCODE ERRIF,ALLIF%
ERCODE ERRID,ALLID%
ERCODE ERRIJ,ALLIJ%
ERCODE ERRIA,ALLIA%
;STILL IN IFN FTGALAXY
;
ALLOC: CAME J,MDAJOB## ;IS HE MDA?
JRST ERRIS ;NO, LOSE
MOVE P1,T1 ;SAVE USER AC
HRR M,T1 ;POINT TO ARG BLOCK
PUSHJ P,GETWDU## ;GET FUNCTION WORD
SKIPL T1 ;TOO SMALL?
CAILE T1,ALLMXF ;TOO BIG?
SETZ T1, ;YES MAKE IT ZERO
JRST @ALLDSP(T1) ;AND DISPATCH
;FUNCTION 1 -- ALLOCATE A DEVICE
;
ALLF1: HLRZ T1,P1 ;GET LENGTH OF ARGLIST
CAIE T1,3 ;MUST BE THREE WORDS
JRST ERRIA ;ILLEGAL ARGLIST
PUSHJ P,GETWD1## ;GET DEVICE WORD
PUSHJ P,ALLFND ;FIND THE DEVICE
PJUMPE F,ERRID ;BAD DEVICE
PUSHJ P,GETWD1## ;GET JOB NUMBER
MOVSI T2,JLOG ;GET JLOG BIT
TDNN T2,JBTSTS##(T1) ;LOGGED IT?
JRST ERRIJ ;NO, GIVE ERROR
DPB T1,PJOBN## ;YES, SET DEVJOB
MOVSI T2,DVDATJ ;GET "ALLOC" BIT
IORM T2,DEVCHR(F) ;SET IT
MOVEI T2,ASSCON!ASSPRG;GET "ASSIGN" BITS
ANDCAM T2,DEVMOD(F) ;AND CLEAR THEM
PJRST CPOPJ1## ;AND RETURN
;FUNCTION 2 - DEALLOCATE A DEVICE
;
ALLF2: HLRZ T1,P1 ;GET LENGTH OF ARGLIST
CAIE T1,2 ;BETTER BE TWO
JRST ERRIA ;ILLEGAL ARGLIST
PUSHJ P,GETWD1## ;GET THE DEVICE
PUSHJ P,ALLFND ;FIND IT
PJUMPE F,ERRID ;LOSE
MOVSI T1,DVDATJ ;GET ALLOC BIT
ANDCAM T1,DEVCHR(F) ;TURN IT OFF
LDB J,PJOBN## ;GET JOB NUMBER
PJUMPE J,CPOPJ1## ;DONE, RETURN
PUSHJ P,DEASG1## ;FORCE A DEASSIGN
JFCL ;IGNORE
PJRST CPOPJ1## ;RETURN
;STILL IN IFN FTGALAXY
;
;SUBROUTINE TO FIND THE SPECIFIED DEVICE (IN TL)
; IF SUCCESSFUL, RETURN WITH F SETUP
; IF NOT, (F)=0
;
ALLFND: PUSHJ P,DEVPHY ;FIND PHYS DEVICE
JUMPE F,CPOPJ## ;RETURN IF NONE
MOVSI T1,DVCMDA ;GET CONTROLLED BIT
TDNN T1,DEVCHR(F) ;TEST IT
CLEAR F, ;FAILED
POPJ P, ;AND RETURN
> ;END IFN FTGALAXY
SUBTTL DEVOP. UUO
;UUO TO PERFORM MISCELLANEOUS DEVICE FUNCTIONS
;
;CALL: MOVE AC,[+N,,ADR]
; DEVOP. AC,0 ;OR CALLI AC,171
; ERROR RETURN
IFN FT5UUO,<
;DEVOP FUNCTIONS ARE EITHER DEVICE INDEPENDENT OR DEVICE DEPENDENT.
; DEVICE INDEPENDENT OPERATIONS ARE HANDLED BELOW, AND DEVICE DEPENDENT
; OPERATIONS ARE HANDLED BY CALLING THE DEVICE SERVICE ROUTINE VIA
; THE DDVO (-4) DISPATCH WITH T1 CONTAINING THE FUNCTION CODE AND F
; POINTING TO THE DDB.
;DEVOP DISPATCH TABLE
; XWD CODE,ADR
DVPDIS: XWD 1,DVPCAL ;(01) LOAD STD VFU (DEP)
XWD 2,DVPCAL ;(02) ENABLE NON-STD VFU LOAD (DEP)
XWD 3,DVPCAL ;(03) DISABLE VFU LOAD
XWD 11,DVPCAL ;(11) LOAD LP RAM
XWD 12,DVPCAL ;(12) LOAD LP VFU
XWD 1000,DVPCAL ;READ/SET PAGE CTR (DEP)
XWD 1002,DVPRHC ;READ/SET DEVICE CHAR (IND)
XWD 1003,DVPRES ;READ ERROR STATUS
XWD 1004,DVPCAL ;READ DEVICE STATUS
DVPDSL==.-DVPDIS ;LENGTH OF DISPATCH
;DEVOP ERRORS
DFACS%==-1 ;ADDRESS CHECK
DFIFC%==0 ;ILLEGAL FUNCTION CODE
DFPRV%==1 ;NO PRIVILEGES
DFDIF%==2 ;FUNCTION NOT VALID FOR SPECIFIED DEVICE
DFNLR%==3 ;VALUE OUT OF RANGE
DFNXD%==4 ;NON-EX DEVICE
DFNDV%==5 ;NO DAVFU
DFNIA%==6 ;DEVICE NOT INITED
DFDOL%==7 ;DEVICE IS OFFLINE
DFCNS%==10 ;PAGE COUNTER NOT SET
DFNPC%==11 ;NO PAGE COUNTER
DFENI%==12 ;EXT ERROR RECOVERY NOT IMP
DFNVC%==13 ;NON VARIABLE CHAR SET
DEVOP:: PUSHJ P,SAVE4## ;SAVE AC'S
MOVE P4,T1 ;RELOCATE USER ARG
HRR M,T1 ;LOAD ADDRESS
HLRE T2,T1 ;GET LENGTH
CAIGE T2,2 ;VALID?
PJRST ECOD3## ;NO
PUSHJ P,GETWRD## ;GET FUNCTION CODE
PJRST RTM1 ;OOPS...BAD GUY
JUMPLE T1,RTZER ;BAD FUNCTION
MOVE P1,T1 ;SAVE FUNCTION
PUSHJ P,GETWR1## ;GET NEXT ARG (DEVICE)
PJRST RTM1 ;LOSE
PUSHJ P,DVCNSG ;SEARCH FOR IT
PJRST ECOD4## ;NONE SUCH
MOVE S,DEVIOS(F) ; AND S
MOVE T1,P1 ;GET FUNCTION
MOVE T2,T1 ;COPY INTO T2
TRNE T2,2000 ;CHANGE SET INTO READ
TRON T2,1000 ; + READ FOR COMPARE
TRZ T2,2000 ; BUT NOT CUSTOMER ARG
HRLZI T3,-DVPDSL ;LOAD AOBJN POINTER
DEVOP1: HLRZ T4,DVPDIS(T3) ;GET CODE
HRRZ P1,DVPDIS(T3) ;GET DISPATCH
CAMN T2,T4 ;MATCH?
JRST (P1) ;YES, DISPATCH T1=FUNCTION
AOBJN T3,DEVOP1 ;NO, LOOP
PJRST ECOD0## ;ILLEGAL FUNCTION CODE
;HERE TO CALL DEVICE SERVICE ROUTINE
DVPCAL: HRRZ T2,DEVSER(F)
PJRST DDVO(T2)
;HERE TO RETURN ERROR STATUS
DVPRES: TRNE T1,2000 ;SET?
PJRST ECOD0## ;YES, ILLEGAL
LDB T1,PDVESE##
PJRST STOTC1##
;HERE TO READ/SET HARDWARE CHARACTERISTICS
DVPRHC: MOVE T2,T1
MOVE T1,DEVHCW(F) ;GET HCW WORD
TRNE T2,1000 ;READ?
PJRST STOTC1## ;YUP, RETURN
PUSHJ P,PRVJ## ;IS JOB PRIVILEGED?
SKIPA ;YES, SKIP
PJRST ECOD1## ;NO.
PUSHJ P,GETWR1## ;GET THE CHARS
PJRST RTM1 ;ADDRESS CHECK
MOVEM T1,DEVHCW(F) ;STORE
PJRST CPOPJ1## ;AND RETURN
> ;END FT5UUO
SUBTTL FILOP. UUO
IFN FT5UUO,<
;UUO TO PERFORM FILE OPERATIONS
;CALL WITH:
; MOVE AC,[N,,E]
; FILOP. AC,
; ERROR RETURN
; NORMAL RETURN
;
;BITS IN THE LH OF FOPFLG
FOP.SA==(1B0) ;THIS FILOP. DOES BOTH A LOOKUP AND
; AN ENTER. WE MUST SAVE ARGUMENTS TILL
; THE ENTER
FOP.LK==(1B1) ;DO A LOOKUP
FOP.EN==(1B2) ;DO AN ENTER
FOP.MA==(1B3) ;MULTI-ACCESS UPDATE
FOP.AP==(1B4) ;APPEND
FOP.PV==(1B5) ;REQUESTING PRIVS.
FOP.NS==(1B6) ;DO NOT SUPERSEDE
FOP.UR==(1B7) ;JUST UPDATE RIB
FOP.NF==(1B8) ;LIT IF INPUT FILE NOT FOUND ON APPEND OR UPDATE
FOP.AL==(1B9) ;PRE-ALLOCATE
FOP.RN==(1B10) ;THIS FILOP. DOES A RENAME
FOP.DL==(1B11) ;THIS FILOP. DELETES THE FILE
FOPTAB: ;DISPATCH TABLE FOR FILOP.
EXP FOPILU ;(00) ILLEGAL
XWD FOP.LK,FOPEN ;(01) READ
XWD FOP.NS+FOP.EN,FOPEN ;(02) CREATE
XWD FOP.EN,FOPEN ;(03) CREATE OR SUPERSEDE
XWD FOP.SA+FOP.LK+FOP.EN,FOPEN ;(04) UPDATE
XWD FOP.SA+FOP.LK+FOP.EN+FOP.MA,FOPEN ;(05) MULTI-ACCESS UPDATE
XWD FOP.SA+FOP.LK+FOP.EN+FOP.AP,FOPEN ;(06) APPEND
EXP FCLOS ;(07) CLOSE
XWD FOP.UR,FCLOS ;(10) UPDATE RIB
EXP FUSTI ;(11) USETI
EXP FUSTO ;(12) USETO
XWD FOP.RN+FOP.LK,FOPEN ;(13) RENAME
XWD FOP.RN+FOP.DL+FOP.LK,FOPEN ;(14) DELETE
XWD FOP.EN+FOP.AL,FOPEN ;(15) PREALLOCATE
FOPMAX==.-FOPTAB-1 ;MAXIMUM FUNCTION
SALL
FILOP: FRAME <FOPFLG,FOPAP,FOPTMP,FOPBLK,FOPEXT>
HRRZM T1,FOPAP ;ADDRESS OF ARG LIST
HLLM M,FOPAP ;AC #
HLRZ T2,T1 ;GET ARGUMENT COUNT
HRR M,T1 ;POINT TO FIRST ARGUMENT
PUSHJ P,GETWDU## ;GET FIRST ARGUMENT
TLZE T1,(1B0) ;DOES HE WANT TO BE PRIV'D?
TLO T2,FOP.PV ;YES--REMEMBER THAT
PUSHJ P,PRVJO## ;IS HE PRIV'ED
TLZ T2,FOP.PV ;NO, CLEAR THE BIT
HLRZ P1,T1 ;REMEMBER CHANNEL #
TLZ T1,17 ;CLEAR OUT CHAN #
CAILE T1,FOPMAX ;FUNCTION TOO BIG?
JRST FOPILU ;YES--ERROR
HLLZ T3,FOPTAB(T1) ;GET FLAGS
IOR T2,T3 ;MAKE FLAGS,,LEN
MOVEM T2,FOPFLG ;SAVE THE FLAGS
DPB P1,PUUOAC## ;IN CASE OF LDB
JRST @FOPTAB(T1) ;DISPATCH BY FUNCTION
;HERE FOR FUNCTIONS WHICH OPEN A FILE
FOPEN: HRRZ T4,FOPFLG ;GET ARG COUNT
CAIGE T4,4 ;MUST BE AT LEAST 4
JRST FOPILU ;ELSE ILL UUO ERROR
IFN FTVM,<
CAIGE T4,6 ;LOOKUP / ENTER GIVEN?
JRST FOPVMX ;NO--ALL VALID
HRRI M,5(M) ;POINTER TO LOOKUP/ENTER BLOCK
PUSHJ P,GETWDU## ;GET POINTER
HRR M,T1 ;PUT IN GOOD AC
HLRZ P2,T1 ;ADDRESS OF THE RENAME BLOCK
PUSHJ P,FCLERB ;CHECK LOOKUP/ENTER/RENAME BLOCK
JUMPE P2,FOPEN0 ;JUMP IF NO RENAME BLOCK
HRR M,P2 ;ADDRESS OF THE RENAME BLOCK
PUSHJ P,FCLERB ;MAKE SURE THATS IN CORE
> ;END FTVM
FOPEN0: CAIGE T4,7 ;PATH POINTER
JRST FOPVMX ;NO--ALL IS WELL
HRR M,FOPAP ;GET ARG POINTER
HRRI M,6(M) ;PATH PTR
PUSHJ P,GETWDU## ;GET ARGUMENT
JUMPE T1,FOPVMX ;JUMP IF PATH ISN'T REQUIRED
HLRZ T2,T1 ;COPY LENGTH
ADDI T2,(T1) ;END ADDRESS
IFN FTVM,<
TLZ T1,-1 ;START ADDRESS
PUSHJ P,TRNGE## ;TEST RANGE
> ;END FTVM
IFE FTVM,<
HRR M,T2 ;GET LAST PATH ADDRESS
PUSHJ P,GETWDU## ;IF ILLEGAL, WON'T RETURN
> ;END FTVM
FOPVMX: HRR M,FOPAP ;GET ARGUMENT POINTER
HRRI M,1(M) ;POINT TO OPEN BLOCK
IFN FTVM,<
MOVE T1,.UPMP+.UPFOP
MOVEM T1,FOPEXT
>
TLO M,400000 ;INDICATE FROM FILOP
PUSHJ P,UOPEN ;TRY TO OPEN
JRST FOPOER ;CAN NOT OPEN
TLZ M,400000
HRRZ T1,FOPFLG ;GET ARG COUNT
CAIN T1,4 ;ONLY DOING AN OPEN?
JRST FOPWIN ;YES--GIVE THE GOOD RETURN
HRR M,FOPAP ;GET ARGUMENT POINTER
HRRI M,4(M) ;POINT TO BUFFER WORD
PUSHJ P,GETWDU## ;GET THE WORD
MOVEM T1,FOPTMP ;SAVE FOR A BIT
HLRE T2,T1 ;GET THE NUMBER OF OUTPUT
; BUFFERS REQUESTED
JUMPE T2,FOPEN1 ;NONE--SKIP OUTBUF
IFN FTVM,<
SKIPN T1,FOPEXT
MOVE T1,.JDAT+JOBFF##
MOVEM T1,.JDAT+JOBFF##
MOVEM T1,.UPMP+.UPFOP
>
SKIPG T2 ;SKIP IF NUMBER GIVEN
MOVEI T2,0 ;ELSE USE DEFAULT
HRR M,T2 ;PUT IN M
PUSHJ P,UOUTBF ;DO THE OUTBUF
FOPEN1: HRRE T1,FOPTMP ;GET THE NUMBER OF INPUT
; BUFFERS REQUESTED
JUMPE T1,FOPEN2 ;JUMP IF NONE REQUESTED
SKIPG T1 ;TURN -1 INTO
MOVEI T1,0 ; ZERO
HRR M,T1
PUSHJ P,UINBF ;BUILD BUFFERS
;HERE TO DO LOOKUP AND/OR ENTER
FOPEN2: HRRZ T1,FOPFLG ;GET # OF ARGUMENTS
CAIN T1,5 ;DONE YET?
JRST FOPWIN ;YES--GIVE SKIP RETURN
HRR M,FOPAP ;GET ARG POINTER
HRRI M,5(M) ;GET POINTER TO LOOKUP BLK
PUSHJ P,GETWDU## ;GET THE POINTER
HRR M,T1 ;SAVE ADDRESS OF BLOCK
HRRM M,FOPBLK ;SAVE ADDRESS FOR LATER
PUSHJ P,GETWDU## ;GET FIRST WORD
MOVE T2,DEVMOD(F) ;GET DEVCHR BITS
TLNE T2,DVDSK ;SKIP IF THIS IS NOT A DISK
TLNE T1,-1 ;SKIP IF EXTENDED UUO
JRST FOPEN3 ;NO DISK OR NOT EXTENDED
TLO P1,400000 ;EXTENDED - INDICATE THAT
HRRI M,UUXNAM(M) ;POINT TO FILE NAME
SKIPA T2,T1 ;YES--COPY COUNT TO T2
FOPEN3: MOVEI T2,4 ;NO--4 WORD BLOCK
TRZ T2,400000 ;IN CASE OF OLD FORMAT
HRLM T2,FOPBLK ;SAVE COUNT
MOVEI T3,UUNEXT-UUNNAM(M) ;WHERE TO FIND EXTENSION
HRLZM T3,FOPEXT ;REMEMBER FOR LATER
MOVE P2,FOPFLG ;GET FLAGS
MOVSI T1,DEPFOP ;WANT TO SET "FILOP. IN PROGRESS BIT"
TLNN P2,FOP.PV ;DOES HE WANT FULL FILE ACCESS
TLO T1,DEPFFA ;NO--MAKE SURE HE DOES NOT GET IT
IORM T1,DEVJOB(F) ;TURN ON BITS IN DDB
MOVEI T1,DEPECS ;NON-SUPERSEDING ENTER
ANDCAM T1,DEVSTA(F) ;CLEAR TO START WITH
TLNE P2,FOP.NS ;WANT TO SUPERSEDE?
IORM T1,DEVSTA(F) ;NO--TELL FNDFIL SUPERSEDE IS ILLEGAL
HRRZ T1,FOPFLG ;# OF ARGUMENTS
MOVE T2,DEVMOD(F) ;DEVICE CHARACTERISTICS
CAIL T1,10 ;8TH ARGUMENT SPECIFIED?
TLNN T2,DVDSK ;ONLY IF A DSK
JRST FOPN3A ;NO
HRR M,FOPAP ;GET ARGUMENT POINTER
HRRI M,7(M) ;POINT TO "IN YOUR BEHALF" PPN
PUSHJ P,GETWDU## ;GET IT
TLNE P2,FOP.PV ;DON'T STORE IF NOT A PRIV'ED PROGRAM INVOKING PRIVS
MOVEM T1,DEVUPP##(F) ;STORE IT FOR FNDFIL
FOPN3A: JUMPGE P2,FOPEN4 ;JUMP IF NOT BOTH LOOKUP AND ENTER
;HERE IF BOTH LOOKUP AND ENTER MUST BE DONE. WE CHANGE THE LENGTH OF
; THE BLOCK (IF REQUIRED) SO THAT WORDS LIKE .RBALC, .RBPOS ETC. ARE
; NOT STORED BUT ARE INSTEAD ARGUMENTS TO THE ENTER.
HLRZ T1,FOPBLK ;REMEMBER SIZE
IFN FTDSIM,<
TLNN P2,FOP.MA ;SIMULTANEOUS UPDATE?
>
CAIGE T1,UUXSIZ+1 ;5 OR MORE WORDS?
JRST FOPEN5 ;NO--DO NOT SAVE ANYTHING
HRR M,FOPBLK ;ADDRESS OF BLOCK
MOVEI T1,UUXPRV+1 ;ONLY NEED PPN/FILE/EXT
PUSHJ P,PUTWDU## ;DON'T LOOK BEYOND
FOPEN4: TLNN P2,FOP.LK ;LOOKUP NEEDED?
JRST FOPEN7 ;NO--SKIP TO ENTER
FOPEN5: HLR M,FOPEXT ;GET EXTENSION ADDRESS
PUSHJ P,GETWDU## ;GET THE EXTENSION
HRRM T1,FOPEXT ;SAVE DATE BITS
SKIPL P1 ;POINT AT PPN WORD -1
AOSA M
SUBI M,UUXEXT-UUXPPN+1
PUSHJ P,GETWD1## ;GET USERS PPN
MOVEM T1,FOPTMP ;AND SAVE IT FOR ENTER
HRR M,FOPBLK ;GET POINTER
MOVE T4,DEVSER(F) ;SETUP FOR DISPATCH
MOVSI T1,DVIN ;ATTEMPTING INPUT
HLRZ T2,FOPEXT ;ADDRESS OF EXT WORD
PUSHJ P,FOPTS ;CHECK DEVICE CHARACTERISTICS
JRST FOPFNF ;SHORT DISPATCH VECTOR
PUSHJ P,UDLK ;DO THE LOOKUP
JRST FOPLER ;LOOKUP ERROR
FOPFNF: ;HERE ON UPDATE OR APPEND FILE NOT FOUND
HRR M,FOPBLK ;POINT TO BLOCK
HLRZ T1,FOPBLK ;GET LENGTH
CAIL T1,UUXPRV+1 ;LONG BLOCK?
PUSHJ P,PUTWDU## ;YES--STORE COUNT BACK
FOPEN7: TLNN P2,FOP.EN ;NEED AN ENTER?
JRST FOPEN8 ;NO--CHARGE AHEAD
HRR M,FOPBLK ;GET BLOCK ADR
SKIPGE P1 ;IF EXTENDED UUO
AOSA M ;POINT M AT THE PPN WORD
HRRI M,UUNPPN-UUNNAM(M) ;POINT TO PPN WORD
MOVE T1,FOPTMP ;INDICATE ENTER IN SAME DIRECTORY AS LOOKUP
TLNE P2,FOP.LK ;DON'T RESTORE PPN WORD IF LOOKUP
; WASN'T DONE.
PUSHJ P,PUTWDU## ;..
IFN FTDSIM,<
MOVE T1,FOPFLG
MOVSI T2,DEPSIM ;IF SIMULTANEOUS ACCESS,
TLNE T1,FOP.MA ;...
IORM T2,DEVJOB(F) ;LIGHT A BIT IN THE DDB
>
MOVEI T1,DEPPAL## ;IF PREALLOCATE,
TLNE P2,FOP.AL
IORM T1,DEVPAL##(F) ;TELL FILUUO
HRR M,FOPBLK ;GET BLOCK POINTER
MOVE T4,DEVSER(F) ;SETUP T4 FOR UDEN
MOVSI T1,DVOUT ;ATTEMPTING OUTPUT
HLRZ T2,FOPEXT ;ADDRESS OF EXT WORD
PUSHJ P,FOPTS ;CHECK DEVICE CHARACTERISTICS
JRST FOPEN8 ;SHORT DISPATCH VECTOR
PUSHJ P,UDEN ;DO THE ENTER
JRST FOPEER ;ENTER ERROR
FOPEN8: TLNN P2,FOP.RN ;RENAME FUNCTION?
JRST FOPN8A ;NO, PROCEED
HRR M,FOPAP ;ARGUMENT POINTER
HRRI M,5(M) ;POINT TO RENAME/DELETE BLOCK
PUSHJ P,GETWDU## ;GET ADDRESS OF RENAME/DELETE BLOCK
HLR M,T1 ;ADDRESS OF BLOCK TO M
HRRM M,FOPBLK ;SAVE ADDRESS OF THE BLOCK
PUSHJ P,GETWDU## ;FIRST WORD OF THE BLOCK
TLNN T1,-1 ;EXTENDED BLOCK
HRRI M,UUXNAM(M) ;YES, POINT AT THE FILE NAME
MOVEI T1,0 ;ASSUME DELETE
TLNE P2,FOP.DL ;IS IT THE DELETE FUNCTION?
PUSHJ P,PUTWDU## ;YES, STORE A ZERO IN THE RENAME BLOCK
MOVEI T1,UUNEXT-UUNNAM(M) ;WHERE THE EXTENSION IS STORED
HRLZM T1,FOPEXT ;SAVE THAT IN CASE OF AN ERROR
MOVE T1,DEVMOD(F) ;DEVICE CHARACTERISTICS
TLNN T1,DVLNG ;LONG DISPATCH VECTOR?
JRST FOPN8A ;NO, DON'T ATTEMPT A RENAME
HRR M,FOPBLK ;RESTORE ADDRESS OF THE RENAME BLOCK
MOVSI T1,DEPFFA ;SO THE CLOSE WILL HAPPEN
ANDCAM T1,DEVJOB(F) ; IN FILUUO (CLRSTS)
MOVE T4,DEVSER(F) ;ADDRESS OF DEVICE DISPATCH VECTOR
PUSHJ P,URENAM ;DO THE RENAME
JRST FOPLER ;RENAME ERROR
FOPN8A: HRRZ T1,FOPFLG ;GET # OF ARGUMENTS
CAIGE T1,7 ;PATH BLOCK GIVEN
JRST FOPEN9 ;NO--ALL IS WELL
HRR M,FOPAP ;GET ARG POINTER
HRRI M,6(M) ;POINT TO PATH WORD
PUSHJ P,GETWDU## ;FETCH POINTER
MOVEM T1,FOPTMP ;SAVE IN PDL
HRR M,T1 ;PATH BLOCK
HLRZ T1,T1 ;GET SIZE
CAIGE T1,3 ;INTERESTING CASE
JRST FOPEN9 ;NO--RETURN
HRRZ T1,P1 ;CHANNEL #
PUSHJ P,PUTWDU## ;STORE FOR PATH. UUO
MOVE T1,FOPTMP ;PRESET AC
PUSHJ P,PTHUUO## ;DO THE PATH UUO
JFCL ;SHULD NEVER FAIL
FOPEN9: MOVE P2,FOPFLG ;GET FLAGS
TLNN P2,FOP.NF ;CREATING INSTEAD OF UPDATING
JRST FOPN9A ;NO--CONTINUE
MOVSI T1,DEPFFA ;YES--FORCE FILE INTO
IORM T1,DEVJOB(F) ; UPDATE MODE
HRRI M,0 ;NO SPECIAL STUFF
PUSHJ P,CLOSE1 ; ..
PUSHJ P,WAIT1## ; ..
FOPN9A: SKIPE P2,FOPFLG ;GET FLAGS
TLNN P2,FOP.AP ;WANT TO APPEND?
JRST FOPWIN ;NO--ALL DONE
MOVE T1,DEVMOD(F) ;IS THIS A DISK
TLNN T1,DVDSK ; ..
JRST FOPN11 ;NO, ALL DONE UNLESS AN MTA
;HERE TO APPEND TO A DISK FILE
FOPN9B: MOVE S,DEVIOS(F) ;GET STATUS BITS
HRRZ T3,DEVACC##(F) ;ADDRESS OF A.T.
MOVE T1,ACCWRT##(T3) ;SIZE OF FILE IN BLOCKS
LDB T2,PIOMOD## ;GET THE MODE
CAIL T2,SD ;DUMP MODE?
JRST FOPN10 ;YES--CAN NOT MERGE DATA
LDB T2,ACZLBS## ;WORD IN LAST BLOCK
TRNN T2,BLKSIZ##-1 ;IF FULL THERE IS NO NEED
JRST FOPN10 ; TO READ IT
;AT THIS POINT WE READ C(T2) WORDS FROM BLOCK C(T1) INTO BUFFER AT C(T3)
MOVEM T2,FOPBLK ;SAVE WORD COUNT
MOVEM T1,FOPTMP ;SAVE BLK #
HLRZ U,DEVBUF(F) ;GET RING ADR
IFN FTKA10,<TLO U,R>
PUSHJ P,OUTF ;ZERO BUFFER
HRRZ T3,DEVOAD(F) ;READ TO HERE
MOVN T2,FOPBLK ;NEG. WORD COUNT
HRLZ T2,T2 ; ..
HRRI T2,1(T3) ; ..
HRLM T2,DEVUVA##(F) ;SAVE IN CASE CHECKSUM NEEDED
ADDI T2,(R) ;FOR MAPIO TO REMOVE
MOVEM T2,DEVDMP##(F) ;SAVE IN DDB
MOVE W,FOPTMP ;BLOCK #
PUSHJ P,FUSETO## ;SETUP POINTERS
MOVEM S,FOPTMP ;SAVE STATUS
TRO S,D ;SET DUMP MODE
TLZ S,IO ;READING
PUSHJ P,UUOSET## ;MAKE EVERYTHING OK
JFCL ;CAN NOT MISS
PUSHJ P,UUOPWQ## ;DO THE I/O
PUSHJ P,PWAIT1## ;WAIT FOR IT
ANDI S,740000 ;PRESERVE ERROR BITS
IORB S,FOPTMP ;RESTORE OLD MODE
MOVEM S,DEVIOS(F) ;SAVE IN DDB
MOVEI J,BLKSIZ## ;WORDS IN BUFFER
SUB J,FOPBLK ;MINUS WORDS WE READ
HLRZ U,DEVBUF(F) ;RING HEADER
IFN FTKA10,<TLO U,R>
HRRZ T2,DEVOAD(F) ;FOR BYTE POINTER
ADD T2,FOPBLK
PUSHJ P,IOSETC ;STORE CORRECT DATA IN HEADER
MOVE J,.C0JOB## ;RESET J
MOVE T1,DEVREL##(F) ;LAST BLOCK WRITTEN
SUBI T1,2 ;REWRITE IT
FOPN10: AOS W,T1 ;BLOCK TO WRITE
PUSHJ P,FUSETO## ;SET POINTERS
JRST FOPWIN ;ALL DONE
FOPN11: TLNN T1,DVMTA ;MAGTAPE?
JRST FOPWIN ;NO, ALL DONE
HRRI M,16
PUSHJ P,DOMTAP ;YES, SKIP TO EOF
JRST FOPXIT ;IO ERROR, LOSE
HRRI M,7
PUSHJ P,DOMTAP ;BACKSPACE OVER EOF
JRST FOPXIT
LDB T1,PIOMOD
CAIL T1,SD ;IF DUMP MODE,
JRST FOPWIN ; WE ARE DONE
PUSHJ P,DOMTAP ;BACKSPACE OVER LAST DATA RECORD
JRST FOPXIT ;IO ERROR
HLRZS U,DEVBUF(F) ;TURN OUTPUT HDR INTO INPUT HDR
IFN FTKA10,<TLO U,R>
PUSHJ P,OUTF ;ZERO BUFFER
HRRZ T1,DEVOAD(F)
HRRM T1,DEVIAD(F) ;READ INTO OUTPUT BUFFER
IFN FTKA10,<TLO T1,R>
EXCTUX <MOVE T2,@T1> ;PICK UP PNTR TO NEXT BUF
EXCTUU <HRRM T1,@T1> ;TURN IT INTO A 1-BUFFER INPUT RING
MOVEM T2,FOPTMP ;SAVE NEXT BUFFER LOC
PUSHJ P,TPMIN## ;READ IN THE LAST RECORD
LDB T1,PUUOAC## ;CHAN NUMBER
TLO F,OUTPB ;IN CASE CLOSE WITH NO OUTPUTS -
MOVEM F,USRJDA##(T1) ; TAPUUO WILL IGNORE IF OUTPB=0
PUSHJ P,WAIT1 ;WAIT FOR IT
MOVE U,DEVBUF(F) ;TURN IT BACK INTO AN OUTPUT HDR
HRLZM U,DEVBUF(F) ;CANT DO INPUT AFTER WRITING A TAPE
IFN FTKA10,<TLO U,R>
HRRZ T1,DEVOAD(F) ;WHERE WE READ
MOVE T3,FOPTMP
IFN FTKA10,<TLO T1,R>
EXCTUU <MOVEM T3,@T1> ;RESTORE BUFFER RING
ADDI T1,1
EXCTUX <MOVE T2,@T1> ;PICK UP WORDCOUNT
HLRZ J,T3 ;MAX WORDCOUNT(+1) OF BUFFER
SUBI J,1(T2) ;AMOUNT LEFT
JUMPE J,FOPN12 ;INIT NEW BUFFER IF NO ROOM IN THIS ONE
ADDI T2,-1(T1) ;POINT T2 TO LAST DATA IN BUFFER FOR IOSETC
PUSHJ P,IOSETC ;SET UP RING HEADER
PUSHJ P,DOMTAP ;BACKSP OVER RECORD SO WILL REWRITE IT
JRST FOPXIT ;LOST!
JRST FOPWIN ;AND TELL USER HE WON
FOPN12: SUBI T1,1 ;POINT AT RIGHT WORD FOR BUFCLR
PUSHJ P,BUFCLR ;ZERO THE BUFFER
JFCL ;SHOULD NEVER HAPPEN
JRST FOPWIN ;AND WE WON
DOMTAP: PUSHJ P,MTAPE0## ;TEL TAPUUO WHAT TO DO
TRNN S,IODERR!IODTER!IOIMPM
AOSA (P) ;WON
MOVEI T1,1 ;LOST, ERROR CODE=1
POPJ P, ;RETURN TO CALLER
;HERE TO DO A USETI AND RETURN STATUS
FUSTI: SKIPA W,[FUSETI##] ;DISPATCH TO USETI
;HERE TO DO A USETO AND RETURN STATUS
FUSTO: MOVEI W,FUSETO## ;DISPATCH TO USETO
PUSHJ P,VALUUO## ;SETUP F AND MAKE SURE DEVICE IS INITED
JRST FOPILU ;NOT A DISK
HRRZ T4,FOPFLG ;NUMBER OF ARGS
CAIE T4,2 ;MUST BE EXACTLY TWO
JRST FOPILU ;IF NOT, LOSE
PUSHJ P,GETWD1## ;GET THE BLOCK NUMBER
EXCH T1,W ;BLOCK NUMBER IN W
PUSHJ P,(T1) ;CALL USET CODE IN FILSER
HRRZ T1,DEVIOS(F) ;I/O STATUS
TRNN T1,760000 ;ERRORS OR END OF FILE?
AOS (P) ;NO, SKIP RETURN TO THE USER
JRST FOPXIT ;DONE
;HERE TO CLOSE A FILE AND RETURN STATUS
FCLOS: MOVE T1,P1 ;COPY CHANNEL
PUSHJ P,DVCNSG ;REAL DEVICE
JRST FCLOSI ;NO--RETURN IOIMPM
HRRZ T2,FOPFLG ;GET LENGTH
SOSE T1,T2 ;ONLY 1 WORD?
PUSHJ P,GETWD1## ;NO--GET FLAGS
HRR M,T1 ;COPY TO CORRECT PLACE
MOVSI T1,DEPFFA ;SET TO JUST UPDATE RIB
MOVSI T2,FOP.UR ;WANT REAL CLOSE?
TDNE T2,FOPFLG ; ..
IORM T1,DEVJOB(F) ;NO--SET DEPFFA
TDNE T2,FOPFLG
HLLZS M ;CLEAR CLOSE-BITS
PUSHJ P,CLOSEF ;CLOSE THE FILE
PUSHJ P,WAIT1## ;WAIT FOR I/O
HRRZ T1,DEVIOS(F) ;GET STATUS
TRNE T1,740000 ;ERROR BITS?
JRST FOPXIT ;DONE
MOVSI T2,FOP.UR ;NO. UPDATE PID?
TDNN T2,FOPFLG
AOSA (P) ;NO. PLAIN CLOSE
SKIPA T1,DEVMOD(F)
JRST FOPXIT
TLNE T1,DVDSK ;DISK?
TLNN F,OUTPB ;YES, HAS IT BEEN WRITTEN?
JRST FOPWIN ;NO, GOOD RETURN
MOVE T2,DEVACC##(F)
SOS T1,DEVREL##(F)
CAMGE T1,ACCWRT##(T2) ;AT EOF?
JRST FOPN10 ;NO, JUST POSITION TO THAT BLOCK
JRST FOPN9B ;YES, POSOTION TO LAST BLOCK
FCLOSI: MOVEI T1,IOIMPM ;SET IOIMPM
PJRST FOPXIT ;DONE
;FILOP. EXIT ROUTINES
FOPWIN: MOVNI T1,1 ;INDICATE SUCCESS
JRST FOPXIT ;STANDARD EXIT
;RIB ERROR
FOPRER: SKIPA T1,[TRNERR]
;ILLEGAL UUO
FOPILU: MOVEI T1,ILUERR ;ERROR CODE
JRST FOPXI1 ;EXIT UUO
;OPEN ERROR
FOPOER: TLZ M,400000
HRR M,FOPAP ;ARG POINTER
HRRI M,2(M) ;POINT TO DEVICE
PUSHJ P,GETWDU## ;FETCH ARGUMENT
PUSHJ P,DEVSRG ;REAL DEVICE?
JRST FOPNSD ;NO SUCH DEVICE
SKIPA T1,[DNAERR] ;DEVICE NOT AVAIL.
FOPNSD: MOVEI T1,NSDERR ;NO SUCH DEVICE
JRST FOPXI1 ;DONE
;LOOKUP AND ENTER ERRORS
FOPLER: TDZA T4,T4 ;FLAG LOOKUP FAILURE
FOPEER: MOVNI T4,1 ;ENTER FAILURE
HLR M,FOPEXT ;ADDRESS OF EXTENSION
PUSHJ P,GETWDU## ;GET THE WORD
IORI T4,(T1) ;COMBINE WITH FLAG
JUMPN T4,FOPXI0 ;JUMP IF NOT FNFERR ON LOOKUP
MOVSI P2,FOP.NF ;SET FILE-NOT-FOUND FLAG
IORB P2,FOPFLG ; ..
TLNN P2,FOP.EN ;ENTER NEEDED
JRST FOPXI0 ;NO--FATAL ERROR ON READ
HRR T1,FOPEXT ;RESTORE DATE BITS
PUSHJ P,PUTWDU## ;STORE FOR ENTER
JRST FOPFNF ;TRY ENTER
FOPXI0: TLZ T1,-1 ;JUST ERROR NUMBER IN T1
MOVEI T2,DEPPAL## ;IF THIS IS A DSK,
MOVE T3,DEVMOD(F)
TLNE T3,DVDSK
ANDCAM T2,DEVPAL##(F) ; CLEAR PRE-ALLOCATE
FOPXIT: MOVSI T2,DEPFOP!DEPFFA ;MUST CLEAR THESE OR DDB
; CAUSE PROBLEMS ON NEXT UUO
ANDCAM T2,DEVJOB(F) ;ZAP!
IFN FTVM,<
SETZM .UPMP+.UPFOP ;FILOP. IS DONE
>
MOVE T2,DEVMOD(F)
TLNE T2,DVDSK ;IF A DSK
SETZM DEVUPP##(F) ;ZERO "IN YOUR BEHALF" PPN
JUMPL T1,CPOPJ1## ;ALL DONE IF NO ERRORS
FOPXI1: LDB M,[POINT 4,FOPAP,12] ;GET AC NUMBER
PJRST PUTWDU## ;STORE CODE AND NON-SKIP RETURN
IFN FTVM,<
;SUBROUTINE TO ENSURE A LOOKUP/ENTER/RENAME BLOCK IS IN CORE
;CALLING SEQUENCE:
; HRRI M,ADDRESS OF THE BLOCK
; PUSHJ P,FCLERB
FCLERB: PUSHJ P,GETWDU## ;GET FIRST WORD OF BLOCK
TLNN T1,-1 ;EXTENDED UUO?
TRZA T1,400000 ;YES--CLEAR OLD STYLE BIT
MOVEI T1,4 ;NO--4 WORDS
HRRZ T2,M ;START ADDRESS
ADDM T1,T2 ;PLUS LENGTH GIVES END
MOVEI T1,(M) ;RESTORE START
PJRST TRNGE## ;MAKE SURE ALL OK
>;END IFN FTVM
;SUBROUTINE TO TEST WHETHER A DEVICE CAN DO THE TYPE OF I/O
; INDICATED AND WHETHER IT HAS A LONG DISPATCH VECTOR OR NOT
;CALLING SEQUENCE:
; MOVSI T1,DVIN OR DVOUT
; MOVE T2,ADDRESS OF THE EXTENSION WORD
; PUSHJ P,FOPTS
;RETURNS CPOPJ IF I/O DIRECTION IS LEGAL BUT DEVICE HAS A
; SHORT DISPATCH VECTOR, CPOPJ1 IF I/O DIRECTION IS LEGAL AND
; DEVICE HAS A LONG DISPATCH VECTOR, CPOPJ2 IF THE I/O DIRECTION
; IS ILLEGAL (FNFERR STORED IN THE EXTENSION WORD OF THE
; LOOKUP/ENTER BLOCK)
;PRESERVES T4
FOPTS: TDNE T1,DEVMOD(F) ;LEGAL I/O DIRECTION?
JRST FOPTS1 ;YES
HRR M,T2 ;NO, ADDRESS OF EXTENSION WORD
PUSHJ P,GETWDU## ;GET THE EXTENSION WORD
HRRI T1,FNFERR ;FILE NOT FOUND ERROR
PUSHJ P,PUTWDU## ;STORE THAT FOR THE USER
JRST CPOPJ2## ;ILLEGAL I/O DIRECTION RETURN
FOPTS1: MOVSI T1,DVLNG ;DEVICE HAS A LONG DISPATCH VECTOR BIT
TDNE T1,DEVMOD(F) ;DOES THE DEVICE HAVE A LONG DISPATCH VECTOR?
AOS (P) ;YES
POPJ P, ;NO
SUBTTL PERF. UUO
PERF.==CPOPJ##
> ;END FT5UUO
SUBTTL CLOSE UUO
;FOR PURPOSES OF COMMENTING THIS SUBROUTINE THE
;TERM 'BUFFER HEADER' SHALL REFER TO THE 3 WORD HEADER
;WHICH IS USED BY THE USER PROGRAM AND THIS EXEC FOR
;REFERING TO THE RING BUFFERS.
;THE CONTENTS OF THE 3 WORD HEADER (AS SET BY THE MONITOR
; ON EACH INPUT AND OUTPUT UUO).
; BIT 18-35=ADDRESS OF SECOND WORD OF THE
; CURRENT BUFFER IN RING WHICH USER IS REFERENCING
; WORD 2: BYTE POINTER TO CURRENT ITEM.
; WORD 3: POSITIVE ITEM COUNT (NO. OF ITEMS LEFT ON
; INPUT, NO. OF FREE ITEMS TO GO ON OUTPUT).
;EACH BUFFER IN THE RING HAS FOLLOWING FORMAT (AS THE USER SEES IT)
; WORD 1: RESERVED FOR BLOCK NUMBER FOR FIXED ADDRESS DEVICES
; WORD 2: BIT 0=USE BIT FOR THIS BUFFER
; BIT 1-17=NO. OF WORDS WHICH FOLLOW (LENGTH OF BUFFER)/
; BIT 18-35=ADDRESS OF SECOND WORD OF NEXT BUFFER IN RING
; WORD 3: LH=LINK TO NEXT BLOCK (SET BY MONITOR FOR DECTAPE)
; RH=NO. OF WORDS OF DATA WHICH FOLLOW (USUALLY
; SET BY EXEC EXCEPT IF THE USER HAS SPECIFIED
; THAT HE WANTS TO COMPUTE WORD COUNT
; HIMSELF INSTEAD OF HAVING THE MONITOR DO IT
; USING THE BYTE POINTER IN THE 3 WORD HEADER).
;CALLING SEQUENCE
; CLOSE D,
; EXIT ALWAYS RETURNS HERE
; THIS ROUTINES PROCESSES THE CLOSE UUO AND DETERMINES WHETHER THE
;OUTPUT ROUTINE SHOULD BE CALLED IF OUTPUT WERE ACTIVE, CLEARS
;THE INPUT BUFFER AREA IF INPUT WERE ACTIVE, AND CLEARS THE
;ITEM COUNTS OF BOTH INPUT AND OUTPUT HEADERS SERVING TO BOTH
;TERMINATE THE USE OF THE DEVICE AND SET THE I/O ROUTINES TO
;ACCEPT ANOTHER INPUT OR OUTPUT COMMAND IN A CLEAR STATE.
;IN THE CASE OF OUTPUT DEVICES, THE CLOSE ROUTINE OF THE DEVICE HANDL-
;ING ROUTINE IS CALLED IN CASE ANY SPECIAL HANDLING IS REQUIRED.
CLOSEF: TDNE T1,DEVJOB(F) ;IF UPDATE-RIB
JRST CLOSE2 ; ALLOW IT WITH LOCKS
CLOSE1::
IFN FTEQDQ,<
PUSHJ P,ENQCLS## ;CHECK FOR LOCKS STILL OUT
SKIPA ;THERE WERE SOME
JRST ENQOK ;THERE WERE NO LOCKS
NQABRT: MOVEI T4,IOBKTL ;SET ERROR BIT...
IORM T4,DEVIOS(F) ;... IN DEVIOS
POPJ P, ;ABORT UUO
ENQOK: >;END OF IFN FTEQDQ
CLOSE2:
IFN FTVM,<SETZM .UPMP+.UPFOP>
HRRZ T4,DEVSER(F) ;RESTORE T4
PUSHJ P,WAIT1## ;WAIT UNTIL DEVICE IS INACTIVE
TRNN M,CLSIN ;SUPPRESS INPUT CLOSE?
TLOE F,ICLOSB ;NO. INPUT ALREADY BEEN CLOSED?
JRST UCLS2 ;YES
LDB T1,PIOMOD## ;NO
CAIGE T1,SD ;DUMP MODE?
JRST UCLSBI ;NO. CLOSE BUFFERED INPUT.
UCLS5: PUSHJ P,DCLI(T4) ;YES. DISPATCH TO DEVICE DEP. ROUTINE
JRST UCLS2 ;MUST NOT DESTROY M,F,T4,W, OR P1-P4
UCLSBI: MOVE T1,DEVMOD(F)
TLNN T1,DVDTA ;IS IT A DTA, OR
TLNE F,INBFB+INPB ;WAS AN INPUT BUFFER SETUP?
JRST UCLS4 ;YES
TLNE T1,DVDSK ;CLOSING A DISK FILE ?
JRST UCLS5 ;YES, DO DEVICE DEPENDENT CLOSE ANYWAY.
JRST UCLS2 ;NO, CLOSE NOT NECESSARY.
UCLS4: TLNE T1,DVLNG ;IS THIS A LONG DISPATCH TABLE?
PUSHJ P,DCLI(T4) ;YES, CLOSE INPUT
HRRZ T2,DEVBUF(F)
JUMPE T2,UCLS2 ;IF NO BUFFER, LOOK FOR OUTPUT SIDE
IFN FTKA10,<
HRLI T2,R
>
HRRZ T1,T2 ;ADDRESS OF THE FIRST WORD OF THE BUFFER HEADER
PUSHJ P,UADRCK ;MAKE SURE ITS IN CORE
EXCTUX <HRRZ U,@T2> ;FIRST WORD OF 3 WORD BUFFER HEADER
EXCTUX <HRR T2,@T2> ;REMEMBER CURRENT BUFFER IN T2
HRLZI T1,IOUSE ;USED BOTH FOR HEADER AND EACH BUFFER
JUMPE U,UCLS1 ;HAS A RING BEEN SETUP?(NO IF 0)
HLL U,T2 ;YES
MOVEI T1,(U) ;IS ADDRESS SPECIFIED BY CONTENTS OF
PUSHJ P,UADRCK ;FIRST WORD OF 3 WORD BUFFER HEADER IN BOUNDS?
MOVEI T3,10000 ;ONLY ALLOW 10000 BUFFERS IN A RING
; SETUP COUNT IN CASE USER HAS MESSED
; BUFFER RING INTO A FIGURE SIX
UCLS0: EXCTUX <HRR U,@U> ;ADVANCE CURRENT INPUT BUFFER ADDRESS
MOVEI T1,(U) ;IS ADDRESS OK?
PUSHJ P,UADRCK
HRLZI T1,IOUSE ;USE BIT FOR BOTH HEADER AND BUFFERS
EXCTUU <ANDCAM T1,@U> ;YES, CLEAR USE BIT.
CAME T2,U ;DONE?
SOJG T3,UCLS0 ;NO, HAVE WE SCANNED 10000 BUFFERS?
; (WHICH MAY BE THE SAME)
; YES
UCLS1: HRR U,DEVBUF(F)
HLL U,T2 ;SET LH(U)
EXCTUU <IORM T1,@U> ;FLAG AS VIRGIN BUFFER IN 3 WORD HEADER
ADDI U,2 ;JBFCTR:=0
IFN FTVM,<
HRRZ T1,U
PUSHJ P,UADRCK ;MAKE SURE ITS IN CORE
>
EXCTXU <SETZM @U> ;CLEAR INPUT ITEM COUNT.
MOVE S,[XWD IOEND,IODEND]
MOVE T1,DEVMOD(F)
TLNE T1,DVTTY ;IS THIS A TTY?
TLO S,FRCEND## ;YES, CLEAR OTHER EOF FLAG
ANDCAB S,DEVIOS(F)
UCLS2: PUSHJ P,UCLS3 ;STORE UPDATED F
TRNN M,CLSOUT ;SUPPRESS OUTPUT CLOSE?
TLOE F,OCLOSB ;NO. OUTPUT ALREADY CLOSED?
JRST UCLS3 ;YES
IFN FT2REL,<
PUSHJ P,RELSEG## ;CLEAR SHARED SEG NAME IF FILE JUST CLOSED HAS
; EXTENSION .SHR AND SEG HAS SAME DIRECTORY AND NAME
>
LDB T1,PIOMOD## ;NO.
CAIGE T1,SD ;DUMP MODE?
JRST UCLSBO ;NO. CLOSE BUFFERED OUTPUT
UCLS7: HRRZ T4,DEVSER(F) ;RESTORE T4
PUSHJ P,DCL(T4) ;YES. DISPATCH TO DEVICE DEP. ROUTINE
JRST UCLS3
UCLSBO: TLNN F,OUTBFB+OUTPB ;WAS AN OUTPUT BUFFER SET UP?
JRST UCLS6 ;NO
HLRZ U,DEVBUF(F) ;VIRGIN OUTPUT BUFFER?
JUMPE U,UCLS6 ;IF NO BUFFER, DON'T CLOSE UNLESS DISK
IFN FTKA10,<
HRLI U,R
>
PUSHJ P,CLSCHK
EXCTUX <SKIPG @U>
JRST UCLS6 ;YES, DO NOT CLOSE UNLESS IT IS A DISK FILE
PUSHJ P,WAIT2X ;ENSURE ALL BUFFERS WRITTEN
UCLS2B: MOVE T4,DEVSER(F)
MOVEI T1,DEPAIO!DEPOND
ANDCAM T1,DEVAIO(F) ;DON'T ALLOW NON-BLOCKING I/O DURING CLOSE
PUSHJ P,DCL(T4) ;CLOSE OUTPUT BUFFER
HLRZ U,DEVBUF(F)
IFN FTKA10,<
HRLI U,R
>
HRLZI T1,IOUSE
EXCTUU <IORM T1,@U>
ADDI U,2
EXCTXU <SETZM @U> ;JBFCTR:=0
PUSHJ P,WAIT1##
MOVSI T1,DEPFFA ;IF FILOP UPDATE - RIB
TDNN T1,DEVJOB(F) ; FILE ISN'T REALLY CLOSED
TLO F,OCLOSB ;SET OCLOSB AFTER OUTPUT IS COMPLETE
UCLS3: LDB T1,PUUOAC##
HLLM F,USRJDA##(T1)
POPJ P, ;EXIT THIS UUO
UCLS6: MOVSI T1,DVDSK!DVDTA
TDNN T1,DEVMOD(F) ;CLOSING A DISK OR DTA FILE ?
JRST UCLS3 ;NO
PUSHJ P,CLSCHK
JRST UCLS7 ;YES, CALL DSK CLOSE ANYWAY
;SUBROUTINE TO CHECK LEGALITY OF BUF HEADER FOR CLOSE
CLSCHK: HLRZ T1,DEVBUF(F) ;START OF BUFFER HEADER
JUMPE T1,CPOPJ
IFN FTVM,<
MOVEI T2,2(T1) ;END
PJRST TRNGE## ;MAKE SURE ITS IN CORE
>
IFE FTVM,<
PJRST UADRCK
>
SUBTTL INBUF & OUTBUF UUO'S
;CALLING SEQUENCE
; INBUF D,N
; EXIT RETURNS HERE IF MEMORY NOT EXCEEDED
;CALLING SEQUENCE
; OUTBUF D,N
; EXIT RETURNS HERE IF MEMORY NOT EXCEEDED
; SETS UP AN N BUFFER RING FOLLOWING THE USER'S PROGRAM FOR DEVICE
; D AND INITIALIZES THE JOB BUFFER AREA HEADER:
; JBFADR0:=1, JBFADR 1-17:=0
; JBFADR 18-35:=ADDRESS OF FIRST BUFFER IN RING
;INPUT SETS DEVIAD:=ADDRESS OF FIRST BUFFER IN RING
;OUTPUT SET DEVOAD:=ADDRESS OF FIRST BUFFER IN RING
;W IS RESTORED.
UINBF:: TLO F,INBFB ;FLAG INBUF UUO DONE
HRRZ T2,DEVBUF(F) ;GET BUFFER HEADER ADDRESS
JUMPE T2,ADRERR## ;ADDRESS CHECK IF NO HEADER
PUSHJ P,BUFCLC ;SET UP BUFFER RING
HRRM T3,DEVIAD(F) ;DEVIAD:=ADDRESS OF FIRST BUFFER
; IN RING
MOVSI T1,DVDSK+DVMTA ;IF A DSK,
TDNE T1,DEVMOD(F) ; SAVE THE NUMBER OF BUFFERS
DPB M,PINBFN## ; IN THE DDB
HRRZ T2,DEVBUF(F) ;T2:=INPUT BUFFER AREA HEADER ADDRESS
JRST UOBF1
UOUTBF::TLO F,OUTBFB ;FLAG OUTBUF UUO DONE
HLRZ T2,DEVBUF(F) ;GET BUFFER HEADER ADDRESS
JUMPE T2,ADRERR## ;ADDRESS CHECK IF NO HEADER
PUSHJ P,BUFCLC ;SET UP BUFFER RING
HLRZ T2,DEVBUF(F) ;T2:=OUTPUT BUFFER AREA HEADER ADDRESS
HRRM T3,DEVOAD(F) ;DEVOAD:=ADDRESS OF FIRST BUFFER
; IN RING
IFN FTMSGSER,<
LDB T1,PDVTYP## ;GET DEVICE TYPE BYTE
CAIN T1,<.TYMPX/.TYEST> ;MPX DEVICE
EXCTUU <HLLZS @T4> ;LIST NOT RING
>
UOBF1:
IFN FTKA10,<
HRLI T2,R ;RELOCATE BUFFER AREA HEADER ADDRESS
>
HRRZ T1,T2 ;CHECK ADR OF BUF HEADER
PUSHJ P,UADRCK
EXCTXU <MOVEM T3,@T2> ;JBFADR:=IOUSE,ADDRESS OF FIRST BUFFER
; IN RING
LDB T1,PUUOAC##
MOVEM F,USRJDA##(T1)
POPJ P, ;EXIT THIS UUO
SUBTTL OPEN & INIT UUO'S
;OPEN UUO - PERFORMS SAME OPERATION AS INIT
;MAY BE USED EASILY BY REENTRANT PROGRAMS
;CALLING SEQUENCE FROM USER AREA
; OPEN D,ADR
; ERROR RETURN
; DEVICE INITED
;LH(ADR)=0,RH(ADR)=DATA MODE THIS INIT
;C(ADR+1) = SIXBIT /NAME/
;LH(ADR+2)=OUTPUT BUFFER HEADER ADDRESS
;RH(ADR+2)=INPUT BUFFER HEADER ADDRESS
UOPEN:: PUSHJ P,GETWDU## ;SET T1 TO CONTENTS OF FIRST ARG(IO STATUS BITS)
AOJA M,UINIT0 ;MAKE UUO POINT TO ARG+1(WITH R STILL
; IN INDEX FIELD)
;CALLING SEQUENCE
; INIT D,MODUS D=JOB DEVICE CHANNEL
; MODUS=IORDEL,IOCON,IOWC,MODE.
; SIXBIT/NAME/ DEVICE NAME
; XWD OBUF,IBUF BUFFER AREA HEADER ADDRESSES
; EXIT1 DEVICE NOT AVAILABLE
; EXIT2 DEVICE PROPERLY ASSIGNED
;THE LEFT HALF OF NAME CONTAINS THE THREE LETTER DEVICE MNEMONIC,
; THE RIGHT HALF IS EITHER ZERO (SYSTEM WILL ASSIGN AN ARBITRARY
; UNIT) OR NON-ZERO TO REQUEST A SPECIFIC UNIT (LEFT JUSTIFIED).
;IF THE SELECTED DEVICE IS NOT AVAILABLE, CONTROL RETURNS TO EXIT1.
;OTHERWISE, THE DEVICE IS ASSIGNED TO THE USER AND ATTACHED TO HIS
;CHANNEL D. THE DEVICE IS INITIALIZED IN THE FOLLOWING MANNER AFTER
;IOACT IS ZERO:
; IOBEG:=1
; DATA MODE:=BITS 32-35 OF AC UUO
; IOCON:=BIT 31 OF AC UUO
; IOWC:=BIT 30 OF AC UUO
; IORDEL:=BIT 29 OF AC UUO
; IOACT:=IODEND:=IOBKTL:=IODTER:=IODERR:=IOIMPM:=0
; JBFADR:=JBFCTR:=0 FOR THE SPECIFIED BUFFERS.
; DEVBUF:=OBUF,IBUF
UINIT:: HRRZ T1,M ;SAVE FIRST ARG(IO STATUS BITS) IN T1
HRR M,-1(P) ;SET UUO TO ADR+1 OF USER ARGS
IFN FTVM,<
PUSHJ P,UINIT0 ;TRY TO INIT THE DEVICE
TDZA T1,T1 ;FAIL
MOVEI T1,1 ;WIN, GIVE SKIP RETURN
ADDI T1,2 ;ACCOUNT FOR THE ARGUMENTS
ADDM T1,-1(P) ;BUMP RETURN PAST THE ARGUMENTS
POPJ P, ;RETURN
>
IFE FTVM,<
AOS -1(P) ;SET RETURN SKIP THE 2 ARGUMENTS
AOS -1(P)
>
UINIT0:
IFN FTEQDQ,<
PUSHJ P,ENQCLS## ;ANY LOCKS OUT?
JRST NQABRT ;YES, ABORT UUO
>
PUSHJ P,SAVE3## ;SAVE P1
PUSH P,M ;HERE ON OPEN UUO, SAVE ADR+1 OF USER ARGS
PUSH P,T1 ;SAVE IO STATUS BITS(FIRST ARG)
SKIPE F,USRJDA##(P1) ;IS A DEVICE ALREADY ASSIGNED TO THIS CHAN?
CAMLE P1,USRHCU## ;YES, IS THIS CHAN. LESS OR EQUAL TO HIGHEST
; CHAN. FOR THIS USER?
JRST UINITA ;NO, NO PREVIOUS DEVICE TO RELEASE
PUSHJ P,RELEA0 ;RELEASE PREVIOUS DEVICE ON THIS CHAN.
UINITA: MOVE M,-1(P) ;RESTORE M (ADR+1 OF 3 ARGS)
PUSHJ P,GETWDU## ;C(T1)=DEVICE NAME IF IN BOUNDS
; DO NOT RETURN IF OUT OF BOUNDS(PRINT ERR AND STOP)
; SET J TO CURRENT JOB NUMBER
IFN FTPHYO,<
SKIPGE (P) ;SIGN BIT OF MODE-WORD=1?
HRLI P1,PHONLY ;YES, SET FOR PHYSICAL DEVICES ONLY
>
PUSHJ P,DEVSRC ;SEARCH FOR DEVICE NAME
; (SET SYSDEV BIT IN LH OF
; F IF THIS IS SYSTEM TAPE)
TDZA T3,T3 ;NO SUCH DEVICE - TRY GENERIC
JRST UINIT2 ;FOUND PHY DEV (OR LOGICAL)
IFE FTGSRC!FTNET,<
PUSHJ P,DEVSRC ;SEARCH FOR DEVICE
>
IFN FTGSRC!FTNET,<
PUSHJ P,DVSRSP ;DOES ANY DEV OF THIS TYPE EXIST?
>
JRST UINITE ;NO - ERROR
IFN FTSPL,<
SKIPN DEVCHR(F) ;IS IT A "FAKE" DDB
SKIPA T2,SPLBIT##(F) ;YES, GET BIT FROM TABLE
LDB T2,DEYSPL## ;YES. GET SPOOLING BIT
HRRZS T2 ;CLEAR TYPE BIT
TDNE T2,JBTSPL##(J) ;JOB SPOOLING THIS DEV?
JRST UINIT2 ;YES. OK
> ;END CONDITIONAL ON FTSPL
MOVEI T3,ASSPRG ;FLAG THAT INIT'ED DEV UNACCEPTABLE
PUSH P,F ;SAVE DDB LOC
IFE FTGSRC,<
PUSHJ P,DEVSRC ;SEARCH FOR DEVICE
>
IFN FTGSRC,<
PUSHJ P,DVASRC ;TRY TO FIND GENERICALLY
>
SKIPA F,(P) ;RESTORE POSSIBLE DDB
JRST UINIT1 ;WON - CONTINUE
TRNE T1,770000 ;IS IT DEVX?
TRNE T1,7700
JRST UINITD ;NO - LOSE
UINIT1: POP P,(P) ;YES - WIN
UINIT2: MOVE T2,JBTSTS##(J) ;IS THIS JOB
TLNE T2,JLOG ; LOGGIN IN?
JRST UINI2A ;YES, CONTINUE
MOVE T2,DEVMOD(F) ;NO, MAKE SURE JOB
TLNN T2,DVDSK!DVTTY ; IS TRYING FOR VALID DEVICE
JRST UINITE ;NO, ERROR
UINI2A: MOVE M,(P) ;RESTORE USER'S MODE SETTING
TLNE M,-1-.OPALL ;ANY UNDEFINED OPEN BITS SET?
JRST ILLMOD## ;YES--BOMB THE USER
PUSH P,T1 ;SAVE NAME USER SUPPLIED
IFN FTNUL,<
CAME T1,[SIXBIT /NUL/] ;ALL MODES ARE LEGAL FOR NUL:
>
PUSHJ P,CHKMOD ;CHECK FOR LEGAL MODE, IF NOT RIGHT DONT RETURN
IFE FTDISK,<
MOVE T1,DEVNAM(F) ;PHYSICAL DEVICE NAME
CAME T1,SYSTAP## ;SYSTEM TAPE DEVICE ?
JRST UINIT1 ;NO, DISK OR NOT SYSTEM TAPE
AOSE STREQ## ;SYSTEM TAPE, INCREMENT REQUEST COUNT
PUSHJ P,STWAIT## ;SYSTEM TAPE BUSY, PUT JOB IN WAIT
MOVEM J,STUSER## ;SET THIS JOB AS ONLY USER OF SYSTEM TAPE
; CONTROL C DOES NOT STOP JOB WHILE USING S. T.
>
POP P,T1 ;RESTORE NAME
MOVE T3,DEVMOD(F) ;DEVICE CHARACTERISTICS
TLNN T3,DVDTA ;IS THIS DEVICE A DECTAPE?
JRST UINITB ;NO
LDB T2,IADPTR## ;YES, GE NO OF USER CHANS DEV INITED ON
HRR T3,T2 ;SAVE OLD NUMBER
AOS T2 ;INCREASE CHANNEL COUNT
DPB T2,IADPTR## ;YES, STORE UPDATED CHANNEL COUNT FOR THIS DEV(DTA)
UINITB: MOVEI T2,ASSPRG ;TRY TO ASSIGN IT BY PROGRAM
SETZM M
PUSHJ P,ASSASG
JRST UINIT6 ;NOT AVAILABLE, GIVE ERROR RETURN(POP T1)
POP P,M ;RESTORE USER'S MODE SETTING
IFN FT5UUO,< ;MISC 5 SERIES UUO FEATURES?
MOVE T2,[XWD DEPIBC,DEPDEL!DEPDER!DEPAIO]
;DISABLE ERROR LOGGING AND ERROR RECOVERY
ANDCAM T2,DEVSTA(F) ;MAKE SURE NOT DISABLED
MOVSI T3,DEPSIE
ANDCAM T3,DEVJOB(F) ;DISABLE SYNCH ON ERROR
TLNN M,.OPDEL ;IS USER TRYING TO DISABLE ERROR LOGGING?
JRST UINIT3 ;NO, LEAVE ERROR LOGGING ENABLED
MOVE J,JOB## ;YES, CURRENT JOB NUMBER
MOVE T2,JBTPPN##(J) ;PROJ PROG NUMBER FOR CURRENT JOB
MOVEI T3,DEPDEL ;SETUP TO STORE DISABLE BIT IN DDB
CAME T2,FSFPPN## ;IS THIS USER FAILSAFE PPN [1,2]?
CAMN T2,UMDPPN## ;NO, IS THS USER MODE DIAG [6,6]?
IORM T3,DEVSTA(F) ;YES, USER PRIVILEGED TO DISABLE ERROR LOGGING
UINIT3: LDB T3,PDVTYP## ;SET DEVTYP WORD
CAIE T3,.TYPTY/.TYEST ;IS IT A PTY?
JRST UINIB1 ;NO, TREAT BIT AS DEPDER
MOVSI T3,DVDIBP ;YES, GET BATCH PTY BIT
ANDCAM T3,DEVCHR(F) ;START WITH IT OFF
PUSHJ P,PRVJ## ;IS JOB PRIV'ED?
SKIPA ;YES, DO THE CHECK
JRST UINIB2 ;NO, IGNORE THE BIT
MOVSI T3,DVDIBP ;LOAD BATCH PTY BIT AGAIN
TLNE M,.OPBJP ;DID USER REQUEST IT?
IORM T3,DEVCHR(F) ;YES TURN IT ON
JRST UINIB2 ;AND CONTINUE ON
UINIB1: MOVEI T3,DEPDER ;SETUP FOR POSSIBLE DISABLE ERROR RETRY
TLNE M,.OPDER ;USER WANT ERROR RETRY DISABLED?
IORM T3,DEVSTA(F) ;YES, SET DISABLE IN DDB
UINIB2: MOVEI T3,DEPAIO ;NON-BLOCKING I/O ON THIS FILE?
TLNE M,.OPAIO ;SKIP IF NO
IORM T3,DEVAIO(F) ;YES, FLAG ASYNCHRONOUS I/O
MOVSI T3,DEPIBC ;INHIBIT BUFFER CLEAR BIT
TLNE M,.OPIBC ;DOES THE USER WANT TO INHIBIT CLEARING OUTPUT BUFFER?
IORM T3,DEVTYP(F) ;YES, REMEMBER THAT
MOVSI T3,DEPSIE ;BIT FOR SYNCH ON I/O ERROR
TLNE M,.OPSIE ;TEST IF USER WANTS IT
IORM T3,DEVJOB(F) ;YES - SET FLG IN DDB
> ;END 5 SERIES UUO FEATURES
HRRZ T2,DEVSER(F) ;GET DISPATCH ADDRESS
;DSZ CALL NEVER RETURNS FOR DC44 DEVICES WHICH ARE DOWN
;THIS EXITS VIA DWNP11 IN ERRCON
PUSHJ P,DSZ(T2) ;LET ROUTINE PUT IN BUF SIZE
DPB T1,PBUFSZ## ;STORE THE BUFFER SIZE IN DEVCHR WORD
PUSHJ P,SETIOS ;SET DDB S STATUS WORD FROM RT. HALF OF AC UUO
; WAIT FOR DEVICES TO BECOME INACTIVE IN CASE IT IS
; INITED ON A DIFFERENT CHANNEL(OR MONITOR COMMAND
; RESPONSE ON TTY)
MOVSI S,IOBEG
IORB S,DEVIOS(F)
HRRZS P1 ;CLEAR LH(P1) FOR UINITL LOOP
UINITL: SKIPL USRHCU## ;SAVGET (CHAN 0)?
CAMG P1,USRHCU## ;NO, IS THIS CHAN. .GT. HIGHEST CHAN. IN USE?
JRST UINITC ;NO
AOS T1,USRHCU## ;YES, BUMP HIGHEST SO FAR BY ONE
SETZM USRJDA##(T1) ;AND CLEAR IT OUT
JRST UINITL ;AND KEEP LOOKING
UINITC: MOVEM F,USRJDA##(P1)
TLO F,INITB+ICLOSB+OCLOSB;SET INIT UUO BIT
;PREVENT SUPERFLUOUS CALLS TO CLOSE (SEE LOOKUP,ENTER)
AOS M,(P) ;ADVANCE TO 3RD ARG(BUFFER HEADER)
PUSHJ P,GETWDU## ;C(T1)=BUFFER HEADER ARG
HLRZ T2,T1 ;OUTPUT BUFFER HEADER FROM USER
JUMPE T2,UINIT4 ;WAS ONE SPECIFIED?
HRLM T2,DEVBUF(F) ;SAVE BUFFER HDR LOC
TLO F,OBUFB ;SET OUTPUT BUFFER SPECIFIED BIT
PUSHJ P,UINITZ ;INITIALIZE OUTPUT BUFFER HEADER
UINIT4: PUSHJ P,GETWDU## ;USER'S ARG AGAIN
HRRZ T2,T1 ;INPUT BUFFER HDR
JUMPE T2,UINIT5 ;WAS ONE SPECIFIED?
HRRM T2,DEVBUF(F)
TLO F,IBUFB ;SET INPUT BUFFER SPECIFIED BIT
MOVSI S,IOEND ;CLEAR END OF FILE FLAG
ANDCAB S,DEVIOS(F) ;AND RETAIN S
PUSHJ P,UINITZ ;INITIALIZE INPUT BUFFER HEADER
UINIT5: MOVEM F,USRJDA##(P1) ;STORE UUO BITS AND DEVICE
; DATA BLOCK ADDRESS
MOVE T1,[XWD R,JOBJDA##] ;PREPARE TO STORE F
ADDI T1,0(P1) ;IN THE RIGHT CHANNEL
MOVEM F,@T1 ;IN THE USERS AREA
MOVE T1,USRHCU## ;AND ALSO HIGHEST CHANNEL
MOVEM T1,JOBHCU##(R) ;TO THE USER AREA
MOVE T1,DEVMOD(F) ;GET THE GOOD WORD
TLNN T1,DVTTY ;IS THIS A TTY?
JRST TPOPJ1## ;SUCCESSFUL RETURN(POP T1)
JRST TTYOPN## ;YES, GO SET UP LDB
UINIT6: PUSHJ P,TTYKLQ## ;IF IT WAS A FREE TTY, DISCARD DDB
TLNE T3,DVDTA ;WAS DEVICE A DECTAPE?
DPB T3,IADPTR## ;YES, RESTORE NO. OF USER CHAN INITED ON
CAIA
UINITD: POP P,(P)
UINITE: POP P,T1 ;REMOVE IO STATUS ARG
JRST TPOPJ## ;AND GIVE ERROR RETURN AND POP T1
;CALLING SEQUENCE
; PUSHJ P,UINITZ
; EXIT RETURNS HERE IF MEMORY NOT EXCEEDED.
;SETS JBFADR:=JBFCTR:=0 FOR THE BUFFER AREA HEADER WHOSE ADDRESS
;IS IN AC T2. ALSO,JBFPTR 0-5:=JBFPTR 12-17:=0,JBFPTR 6-11:=BYTE SIZE
UINITZ::
IFN FTKA10,<
HRLI T2,R ;SET FOR RELOCATION
>
IFE FTVM,<
MOVEI T1,2(T2) ;CHECK 3RD WORD OF BUFFER HEADER
PUSHJ P,UADRCK
>
IFN FTVM,<
MOVEI T1,(T2) ;START ADR OF HEADER
MOVEI T2,2(T1) ;TOP ADR
PUSHJ P,LRNGE## ;MAKE SURE WHOLE HEADER IS IN CORE
MOVEI T2,-2(T2) ;RESET T2
>
SKIPL M ;IF NOT FROM FILOP,
EXCTXU <SETZM @T2> ; CLEAR FIRST WORD (CURRENT BUFFER) OF 3 WORD HEADER
AOS T2 ;POINT TO SECOND WORD (BYTE POINTER)
PUSH P,T2
AOS T2 ;POINT TO THIRD WORD (ITEM COUNT)
EXCTXU <SETZM @T2> ;SET ITEM COUNT TO ZERO
PUSHJ P,SETBYT ;SET BYTE SIZE ACCORDING TO MODE AS SET IN AC S
POP P,T2 ;GET T2 BACK
TLZ T1,770077
EXCTUU <HLLM T1,@T2> ;AND STORE IN SECOND WORD
POPJ P, ;RETURN
SUBTTL COMMON PART OF LOOKUP AND ENTER
;LONG DISPATCH TABLE UUOS - GET HERE ONLY IF DEVICE HAS LONG
;DISPACTH TABLE
;DISPACTH TO DEVICE DEPENDENT SERVICE ROUTINE
;ENTER UUO - ENTER FILE NAME IN DIRECTORY
UDEN: PUSHJ P,SAVE4##
IFN FTEQDQ,<
PUSHJ P,ENQCLS## ;LOCKS STILL OUT?
JRST LKNQER ;YES
>
MOVEI T1,CLSIN
TLNN F,OCLOSB ;FILE OPEN?
PUSHJ P,UDLKC ;YES. CLOSE IT[OCLOSB_1]
MOVSI S,IOBEG ;RESET BITS IN S
IORM S,DEVIOS(F) ; (CAN'T DO A MOVEM DUE TO
MOVEI S,IOIMPM!IODERR!IODTER!IOBKTL!IODEND!IOBOT!IOTEND
ANDCAB S,DEVIOS(F) ; POSSIBLE RACE WITH SERVICE ROUTINE)
PUSHJ P,ARGCHK ;ADDRESS CHECK ARG.
PUSHJ P,DEN(T4) ;ATTEMPT AN ENTER
POPJ P, ;FAILURE
TLZ F,OCLOSB
TLO F,ENTRB ;NOTE SUCCESSFUL ENTER
JRST DLKDEN ;STORE THE PROGRESS BITS
;LOOKUP UUO - LOOKUP FILE NAME IN DIRECTORY
UDLK: PUSHJ P,SAVE4##
IFN FTEQDQ,<
PUSHJ P,ENQCLS## ;LOCKS STILL OUT?
JRST LKNQER ;YES
>
MOVEI T1,CLSOUT ;INHIBIT OUTPUT CLOSE BIT
TLNN F,ICLOSB ;FILE OPEN?
PUSHJ P,UDLKC ;YES. CLOSE IT[ICLOSB_1]
MOVE S,[XWD IOEND,IOIMPM!IODERR!IODTER!IOBKTL!IODEND!IOBOT!IOTEND]
ANDCAB S,DEVIOS(F)
PUSHJ P,ARGCHK ;ADDRESS CHECK ARG.
MOVE T4,DEVSER(F)
PUSHJ P,DLK(T4) ;ATTEMPT A LOOKUP
POPJ P, ;FAILURE
TLZ F,ICLOSB
TLO F,LOOKB ;NOTE SUCCESSFUL LOOKUP
DLKDEN: HLLM F,USRJDA##(P1) ;STORE UUO PROGRESS BITS
JRST CPOPJ1## ;SUCCESS RETURN TO USER (CALL+2)
IFN FTEQDQ,<
LKNQER: PUSHJ P,GETWDU## ;GET ADDRESS OF LOOKUP BLOCK
TLNN T1,-1 ;IS IT AN EXTENDED ONE?
ADDI M,2 ;YES
PUSHJ P,GETWD1## ;GET CONTENTS OF WORD
HRRI T1,ENQERR ;SET ERROR CODE
PJRST PUTWDU## ;RETURN IT TO USER
>
UDLKC:: PUSH P,M
PUSH P,T4
HRRI M,(T1)
PUSHJ P,CLOSE1
POP P,T4
POP P,M
JRST WAIT1##
ARGCHK: MOVEI T1,0(M)
PUSHJ P,UADCK1 ;CHECK FIRST WORF OF TABLE
MOVEI T1,3(M) ;LOAD UP LAST WORD OF TABLE
PJRST UADCK1 ;ADDRESS CHECK IT
SUBTTL COMMON PART OF RENAME, USETI/O, UGETF AND UTPCLR
;RENAME UUO - HERE ON SHORT DISPATCH TABLE DEVICES TOO
URENAM: MOVE T1,DEVMOD(F) ;IS THIS DEVICE A LONG DISPATCH TABLE?
TLNN T1,DVLNG
JRST CPOPJ1## ;NO, GIVE SKIP RETURN TO USER
PUSHJ P,ARGCHK ;ADDRESS CHECK END OF BLOCK
IFE FT2REL,<
JRST DRN(T4) ;YES, DISPATCH TO SERVICE ROUTINE
>
IFN FT2REL,<
JRST RNMSEG## ;OLD FILE IS .SHR AND RENAME SUCCESSFUL.
>
;SETO UUO - SET NEXT OUTPUT BLOCK NUMBER(DECTAPE)
UDSO: PUSHJ P,WAIT2 ;WAIT FOR IO, FIX OUTPUT BUFFERS
JRST DSO(T4)
;SETI UUO - SET NEXT INPUT BLOCK NUMBER
UDSI: PUSHJ P,WAIT2 ;WAIT FOR IO, FIX OUTPUT BUFFERS
JRST DSI(T4)
;GETF UUO - GET NEXT FREE BLOCK
UDGF: JRST DGF(T4)
;MTAPE UUO - MAGTAPE OPERATIONS
UMTAPE: JRST DMT(T4)
;UTPCLR - CLEAR DECTAPE DIRECT.
UTPCLR: MOVE T1,DEVMOD(F) ;IS THIS A LONG DISPATCH TABLE?
TLNN T1,DVLNG
POPJ P, ;NO,RETURN
JRST DCLR(T4) ;YES, DISPATCH
SUBTTL COMMON PART OF INPUT AND OUTPUT UUO'S
;INPUT UUO
;1) IF OUTPUT ACTIVE ON THIS CHANNEL, WAIT FOR IT TO COMPLETE.
;2) IF DUMP MODE, WAIT FOR DEVICE INACTIVE, CALL SERVICE
; ROUTINE TO START INPUT, WAIT TILL COMPLETE, THEN RETURN TO USER.
;3) IF NO BUFFER RING SETUP, SET UP 2 RING BUFFER.
;4) IF FIRST REFERENCE, START SERVICE ROUTINE, GO TO
;5) FLAG CURRENT BUFFER AS FREE TO RECEIVE MORE INPUT
; (USE BIT SET TO 0).
; START SERVICE ROUTINE FILLING FIRST BUFFER WITH USE BIT 0
; (NEXT BUFFER OR ONE AHEAD OF IT)
; (SERVICE ROUTINE WILL SET USE BIT WHEN IT FINISHES FILLING
; BUFFER).
;7) IF NEXT INPUT BUFFER IS FULL OF DATA, GO TO 10).
;8) PUT JOB IN IO WAIT TILL NEXT BUFFER FILLED.
;9) IF NEXT INPUT BUFFER STILL NOT FILLED, CHECK FOR END
; OF FILE OR ERROR BITS SET BY SERVICE ROUTINE.
;10) CONVERT WORD COUNT AS STORED BY SERVICE ROUTINE IN THIRD
; WORD OF BUFFER TO ITEM COUNT AND STORE IN THIRD WORD
; OF HEADER (ITEM COUNT) ALSO SET BYTE POINTER (SECOND
; WORD OF HEADER) AND RETURN TO USER.
CNGIN: TRNN M,-1 ;IS USER CHANGING RINGS
POPJ P, ;NO - RETURN IMMEDIATELY
PUSHJ P,WAIT1## ;WAIT FOR I/O TO COMPLETE
TRNN T2,-1 ;DID HE HAVE A PREVIOUS BUFFER?
JRST SETNEW ;NO - SKIP NEXT
HRRZ T1,T2 ;MAKE SURE THAT BUFFER WAS
PUSHJ P,UADRCK ;IN HIS ADDRESS SPACE
HRLZI T1,IOUSE ;BUFFER IN USE BIT
EXCTUU <ANDCAM T1,@T2> ;AND THEN MAKE IT AVAILABLE
SETNEW: EXCTUU <HRRM M,@U> ;POINT HEADER TO NEW RING
HRR T2,M ;AND RESET PTR TO CURRENT BUFFER
HRLZI T1,IOUSE ;BUFFER IN USE BIT
EXCTUU <IORM T1,@U> ;VIRGIN BIT FOR NEW RING
MOVE S,DEVIOS(F) ;LOAD S JUST IN CASE
POPJ P,0 ;RETURN WITH TRANSPARENT CHANGES
UIN: IFN FTPI,< ;IF WE SUPPORT PSISER
XCT OKSGNL## ;IS AN INTERRUPT REMOTELY POSSIBLE?
JRST UIN00 ;NO--BE FAST
PUSHJ P,UIN00 ;YES--DO THE INPUT
PJRST PSIIDN## ;CALL PSISER TO SEE IF ANYTHING HAPPENED
> ;END FTPI
UIN00: TLNE S,IO ;IS THIS DEVICE ALREADY DOING OUTPUT?
JRST [MOVE T1,DEVMOD(F)
TLNN T1,DVTTY
PUSHJ P,WAIT2
JRST .+1]
TLO F,INPB ;FOR THIS DEVICE.
TLZ F,ICLOSB
HLLM F,USRJDA##(P1) ;IN LH OF CURRENT JOB DEVICE CHANNEL
LDB T1,PIOMOD## ;IO MODE
CAIL T1,SD ;IT THE IO MODE DUMP(SD,D,DR)?
JRST INDMP ;YES
IN1: HRRZ U,DEVBUF(F) ;NO, GET ADDRESS OF BUFFER HEADER
IFN FTKA10,<
HRLI U,R ;SET INDEX FIELD FOR RELOCATION USING AC R
>
IFE FTVM,<
MOVEI T1,2(U) ;CHECK BUFFER HEADER
PUSHJ P,UADRCK
>
IFN FTVM,<
HRRZ T1,U ;START OF HEADER
MOVEI T2,2(T1) ;TOP OF HEADER
PUSHJ P,LRNGE## ;MAKE SURE ITS ALL THERE
>
MOVE S,DEVIOS(F) ;SETUP IO STATUS AGAIN FORM FROM MEMORY
; AC S IS CLOBBERED BY AUTOMATIC CORE EXPANSION
; ON AN IMPLICIT INBUF ON FIRST INPUT
EXCTUX <MOVE T2,@U> ;GET WORD 1 OF 3 WORD BUFFER HEADER.
HLL T2,U ;SET INDEX FIELD FOR RELOCATION USING AC R
PUSHJ P,CNGIN ;GO SEE IF USER CHANGING RINGS
HRRZ T1,T2 ;CHECK ADR. TO SEE IF OK
PUSHJ P,UADCK1
EXCTUX <SKIPG @U> ;HAS A BUFFER RING BEEN SET UP (RH NON-ZERO)
; WHICH HAS BEEN REFERENCED BY PREVIOUS INPUT (BIT0=0)
JRST INPUTF ;NO. GO SET UP BUFFER IF NECESSARY AND DO FIRST IO
MOVE S,DEVIOS(F)
HRRZ T1,DEVIAD(F) ;BUFFER ADR DEVICE WILL USE
TDNN S,[XWD IOEND,IOACT] ;BUFFER HAS BEEN ADR CHECKED IF I/O IS ACTIVE
PUSHJ P,UADRCK ;MAKE SURE IT'S LEGAL
HRLZI T1,IOUSE ;BUFFER IN USE BIT
EXCTUX <TDNN T1,@T2>
JRST INPT1
IFN FTVM,<
EXCTUX <HRRZ T1,@T2> ;MAKE SURE A FAULT WONT HAPPEN
PUSHJ P,FLTST## ; BEFORE WE ADVANCE THE BUFFER HEADER
JRST UUOFLT## ;OOPS - GET THE PAGE IN CORE
EXCTUX <SKIPGE T2,@T1>
MOVSI T2,1 ;WRD 1 MUST BE IN CORE
HLRZS T2
ADDI T2,(T1)
PUSHJ P,LRNGE##
EXCTUX <HRRZ T2,@U>
>
MOVEI T3,DEPIND ;DID WE RETURN EARLY BEFORE?
TDNE T3,DEVAIO(F) ; (ASYNC. IO, BUFFER NOT FULL)
JRST INPT3 ;YES, DON'T ADVANCE BUFFERS NOW
IFN FTVM,<
IFN FTMSGSER,<
LDB T1,PDVTYP## ;GET DEVICE TYPE
CAIE T1,<.TYMPX/.TYEST>
JRST INPT0E ;NO--CHARGE AHEAD
HRR T1,DEVBUF(F) ;GET ADDRESS OF INPUT BUFFER HEADER
MOVEI T2,3(T1) ;TOP OF H-WORD HEADER
PUSHJ P,TRNGE## ;MAKE SURE IT'S IN CORE
INPT0E:> ;END FTMSGSER
MOVSI T1,IOUSE
EXCTUX <HRRZ T2,@U> ;RESTORE T2
> ;END FTVM
EXCTUU <ANDCAB T1,@T2> ;FLAG CURRENT BUFFER AS FREE TO
; RECEIVE MORE INPUT, CLEAR USE BIT
; AND GET POINTER TO NEXT BUFFER
HRRZS T1 ;AND CHECK ITS ADDRESS TO SEE IF IN BOUNDS
PUSHJ P,UADRCK
EXCTUU <HRRM T1,@U> ;SET WORD 1 IN 3 WORD HEADER TO NEXT BUFFER
TRNE S,IOACT ;IS THE DEVICE ALREADY ACTIVE
JRST INPT0C ;YES
MOVE T3,DEVMOD(F) ;GET DEVICE CHARACTERISTIC WORD
TLNN T3,DVTTY ;IS IT A TTY?
TRNE S,IOCON ;DISCONTINUOUS MODE?
JRST INPT0B ;YES, LOOK AT FIRST BUFFER (NOT NEXT)
IFN FTVM,<
SKIPN .UPMP+.UPREL
SKIPE .UPMP+.UPVRT ;IF JOB IS VIRTUAL
JRST INPT0F ; DONT TRY N-BUF LOOKAHEAD
>
TLNN T3,DVDSK+DVMTA ;IF A DISK,
TDZA T3,T3
LDB T3,PINBFN## ;TRY N/2 - BUFFER LOOKAHEAD (N-BUF RING)
LSH T3,-1 ;TRY 1-BUFFER LOOKAHEAD IF NOT A DISK
HLL T1,U ;SET RELOCATION IF A KA
INPT0T: EXCTUX <HRRZ T1,@T1> ;GET LOC OF NEXT BUFFER
PUSHJ P,UADRCK ;MAKE SURE ITS OK
SOJLE T3,INPT0B ;LAST BUFFER TO CHECK IF T3 = 0
HLL T1,U ;NOT LAST TO CHECK (IF FULL)
EXCTUX <SKIPGE @T1> ;IS IT FULL?
JRST INPT0T ;YES, CHECK NEXT
JRST INPT0G ;NO, START IO INTO THIS BUFFER
IFN FTVM,<
INPT0F: PUSHJ P,FLTST## ;IS THIS BUFFER IN CORE?
JRST INPT0D ;NO. GO BACK TO FIRST
EXCTUX <HLRZ T3,@T1>
TRZ T3,IOUSE ;YES, IS THE WHOLE BUFFER IN CORE?
ADDI T1,(T3)
PUSHJ P,FLTST##
INPT0D: EXCTUX <SKIPA T1,@U> ;NO, GO BACK TO FIRST BUFFER
SUBI T1,(T3) ;YES, START IO FOR THIS BUFFER IF EMPTY
PUSHJ P,UADRCK
>
INPT0B: HLL T1,U ;SET RELOCATION AGAIN
EXCTUX <SKIPL @T1> ;IS THE USE BIT SET?
INPT0G: PUSHJ P,CALIN ;NO, START SERVICE ROUTINE FILLING EMPTY BUFFER
INPT0C: EXCTUX <HRR T2,@T2> ;GET USE BIT FOR NEXT BUFFER
INPT0A: EXCTUX <SKIPGE @T2> ;IS USE BIT SET YET?(BUFFER FILLED YET?)
JRST INPUT2 ;YES, RETURN IMMEDIATELY TO USER
INPT2: MOVEI T1,DEPAIO ;ASYNCHRONOUS IO?
TDNN T1,DEVAIO(F) ;YES, DON'T BLOCK THE JOB
PUSHJ P,WSYNC## ;NO, PUT JOB IN IO WAIT TILL BUFFER FILLED.
INPT3:
IFN FTMSGSER,<
PUSHJ P,CHKMPX## ;AN MPX DDB OR A DDB CONNECTED TO AN MPX?
JRST INPT3A ;YES, LET MSGSER WORRY ABOUT TROUBLE
>
TLZE S,IOSTBL ;RECOVERABLE ERROR?
JRST INPT1 ;YES, TRY AGAIN
INPT3A: EXCTUX <SKIPL @T2> ;RETURN WHEN BUFFER FILLED. CHECK TO MAKE SURE.
JRST INEOF ;NO, MUST BE EOF OR ERROR
INPUT2: ADDI T2,1 ;YES, GET WORD COUNT AS SET BY IO SERVICE
IFN FTMSGSER,<
LDB J,PDVTYP## ;GET THE DEVICE TYPE
CAIE J,<.TYMPX/.TYEST> ;MPX: ?
JRST INPT2A ;NO--IGNORE 4-TH WORD
EXCTUX <HLRZ J,@T2> ;PICK UP THE UDX
MOVE T1,U ;ADDRESS OF RING HEADER
ADDI T1,3 ;GET TO FORTH WORD
EXCTUU <MOVEM J,@T1> ;STORE FOR USER TO SEE
INPT2A:>
EXCTUX <HRRZ J,@T2> ;RH OF 3RD WORD(FIRST SO-CALLED DATA WORD)
MOVEI T1,DEPIND
ANDCAM T1,DEVAIO(F) ;DON'T WANT TO USE BUFFER AGAIN
SOJA T2,IOSETC ;SET ITEM COUNT AND BYTE POINTER
; IN 3 WORD HEADER AND RETURN TO USER
INPT1: TRNN S,IOACT ;IF DEVICE ISNT ALREADY GOING
PUSHJ P,CALIN ; START IT NOW
JRST INPT2 ;BLOCK UNTIL BUFFER FILLED
INEOF: TDNN S,[XWD IOEND,IODERR+IOBKTL+IODTER+IOIMPM]
; EOF OR ERROR BIT SET BY SERVICE ROUTINE
JRST INEOF1 ;MONITOR ERROR
TLNE S,IOEND ;IS THIS EOF?
TRO S,IODEND ;YES, SET USER EOF BIT.
IORB S,DEVIOS(F)
IFN FTKI10!FTKL10,<
TRNN S,IOACT ;DEVICE ACTIVE?
PUSHJ P,RTEVMI## ;RETURNS EXEC VIRTUAL MEMORY IF ANY
>
POPJ P, ;RETURN TO USER'S PROGRAM
INEOF1: MOVE T1,DEVAIO(F) ;ASYNC?
TRNN T1,DEPAIO
JRST UUOER1## ;NO-MONITOR ERROR
MOVEI T1,DEPIND
IORM T1,DEVAIO(F) ;YES, INDICATE WE RETURNED EARLY
POPJ P,
;HERE ON FIRST INPUT AFTER INIT, INIT & LOOKUP, OR INIT & LOOKUP & INPUT
INPUTF:
IFN FTVM,<
JUMPE T1,INPTF1 ;IF A BUFFER ADR IS SPECIFIED,
PUSHJ P,BRNGE## ;MAKE SURE WHOLE BUFFER IS IN CORE
EXCTUX <HRRZ T2,@U> ;RESET T2
INPTF1:>
HRLZI T3,IOUSE ;BUFFER IN USE BIT
EXCTUU <ANDCAB T3,@U> ;MARK THAT BUFFERS HAVE BEEN REFERENCED
; BY CLEARING SIGN BIT OF 1ST WORD
; IN 3 WORD BUFFER HEADER
JUMPE T3,INPUT3 ;HAS A RING BEEN SET UP YET?
HRRZ T1,T2 ;YES ADDRESS CHECK FIRST USER BUFFER
PUSHJ P,UADRCK ;
EXCTUX <SKIPG @T2> ;IS USE BIT SET IN FIRST USER INPUT BUFFER?
; CAN HAPPEN IF TTY AND USER HAS TYPED
; IN LINE AFTER INBUF BUT BEFORE FIRST INPUT UUO
JRST INPUT2 ;YES, DO NOT CALL SERVICE ROUTINE(SCNSER)
; SINCE USER BUFFER ALREADY HAS DATA
PUSHJ P,WAIT1## ;WAIT FOR I/O TO STOP
HRRM T3,DEVIAD(F) ;YES, STORE ADR. OF 2ND WORD OF
; A BUFFER FOR SERVICE ROUTINE
PUSHJ P,CALIN ;YES. GO START IO SERVICE ROUTINE
; FILLING BUFFER
JRST INPT0A
INPUT3: HLLZS M ;USE DEFAULT NO OF BUFFERS
PUSHJ P,UINBF
HLLZS M ;CLEAR RIGHT HALF
JRST IN1
CALIN:: MOVSI S,IOSTBL ;RESET ERROR FLAG
IFN FTMSGSER,<
PUSHJ P,CHKMPX## ;AN MPX DDB OR A DDB CONNECTED TO AN MPX?
MOVEI S,0 ;YES, DON'T CHANGE THE STATE OF TROUBLE
>
ANDCAB S,DEVIOS(F) ; IN DDB AND S
TLNE S,IOEND
POPJ P,
PUSH P,T2
PUSH P,U
HRRZ T1,DEVIAD(F) ;IS FIRST ADR. ABOVE JOB DATA AREA?
IFE FTVM,<
PUSHJ P,UADRCK
>
IFN FTKA10,<
HRLI T1,R ;RELOCATE KA10 STYLE
>
EXCTUX <HLRZ T2,@T1> ;GET LENGTH OF BUFFER
MOVE T3,DEVMOD(F)
TLNE T3,DVTTY
TRZ T2,IOUSE ;CLEAR USE BIT IN CASE IT IS ON(TTY)
IFE FTVM,<
HRRZS T1
ADDI T1,(T2) ;TOP ADR IN BUFFER
PUSHJ P,UADRCK ;CHECK IT
>
IFN FTVM,<
ADDI T2,(T1) ;TOP ADR
SUBI T1,1 ;1ST ADR-1 (WHERE ADVBFE STORES)
PUSHJ P,LRNGE## ;MAKE SURE WHOLE BUFFER IS IS CORE & LEGAL
>
IFN FTKI10!FTKL10,<
PUSHJ P,GTIEVM## ;GET EVM FOR THIS INPUT OPERATION IF THE
; DEVICE REQUIRES IT
>
MOVE T4,DEVSER(F)
PUSHJ P,DIN(T4) ;DISPATCH TO IO SERVICE ROUTINE
MOVE J,.CPJOB##(P4) ;RESTORE J
POP P,U
PJRST T2POPJ## ;RESTORE T2 AND RETURN
;CALLING SEQUENCE
; OUTPUT D,
; EXIT
;OR
; OUTPUT D, ADR
; EXIT
;IF INPUT IS ACTIVE, WAIT FOR IT TO COMPLETE.
;IF DUMP MODE WAS SELECTED BY THE LAST INIT UUO OR SETSTS UUO
; THE PROGRAM WAITS UNTIL THE DEVICE IN INACTIVE AND THEN
; WRITES THE DUMPFILE AND RETURNS CONTROL TO THE USER'S PROGRAM
; WHEN IO HAS COMPLETED.
;IF THE MODE IS NOT DUMP, THEN
;1) IF ADR IS NOT ZERO, WAIT FOR DEVICE TO BECOME INACTIVE THEN SET THE
; CURRENT BUFFER ADDRESS EQUAL TO ADR AND AN INDICATOR (JBFADR0)
; SPECIFYING THAT THIS BUFFER RING HAS NEVER BEEN REFERENCED FROM THE
; USER'S PROGRAM BY AN INPUT OR AN OUTPUT UUO. OTHERWISE, GO TO
; 2) DIRECTLY.
;2) IF THE BUFFER RING HAS NEVER BEEN REFERENCED (JBFADR0=1), THE
; BUFFER IS CLEARED, IOUSE SET TO ZERO AND
; IF THE CURRENT BUFFER ADDRESS IS ZERO, A TWO BUFFER RING IS SET UP.
; THEN GO TO 8
;
;3) IF THE BUFFER RING HAS BEEN REFERENCED (JBFADR0=0 ,THEN A CHECK IS
; MADE TO DETERMINE IF THE WORD COUNT IS TO BE COMPUTED.
; IF THE WORD COUNT IS TO BE COMPUTED (IOWC=0), IT IS SET EQUAL
; TO THE ADDRESS FOR THE LAST DATA WORD MINUS THE ADDRESS OF THE
; BUFFER MINUS ONE.
;4) IOUSE IS SET TO ONE, INDICATING THAT THE BUFFER IS FULL OR BEING
; EMPTIED, AND THE CURRENT BUFFER ADDRESS IS ADVANCED.
;5) IF THE DEVICE IS NOT ACTIVE (IOACT=0), OUTPUT IS STARTED.
;6) IF THE CURRENT BUFFER IS FULL OR BEING EMPTIED (IOUSE=1),
; THE PROGRAM WAITS UNTIL THE DEVICE FINISHES THE BUFFER
; (THE OUTPUT SERVICE ROUTINE CLEARS THE USE BIT WHEN
; IT FINISHES OUTPUTTING A BUFFER).
;7) THE CURRENT BUFFER IS CLEARED.
;8) THE J POINTER IS INITIATED TO THE CURRENT BUFFER ADDRESS+1
; AND THE ITEM COUNT IS SET TO THE PRODUCT OF THE BUFFER SIZE
; MINUS ONE AND THE INTEGER PART OF 36/BYTE SIZE.
;9) RETURN TO THE USER'S PROGRAM
;HERE ON OUTPUT UUO
UOUT: IFN FTPI,< ;IF WE SUPPORT PSISER
XCT OKSGNL## ;DID USER DO A PIINI UUO?
JRST UOUT00 ;NO--CHARGE AHEAD
PUSHJ P,UOUT00 ;YES--DO OUTPUT
PJRST PSIODN## ;CALL PSISER TO LOOK FOR INTERRUPTS
>
UOUT00: TLO F,OUTPB ;SET OUTPUT UUO BIT
TLZ F,OCLOSB ;CLEAR CLOSE OUTPUT BIT
HLLM F,USRJDA##(P1) ;SAVE NEW BIT SETTINGS.
IFN FTMSGSER,<
LDB T1,PDVTYP## ;GET THE DEVICE TYPE
CAIN T1,<.TYMPX/.TYEST> ;IS THIS MPX?
PJRST MSGOUT## ;YES--CALL MSGSER
> ;END FTMSGSER
;HERE FROM DEVICE SERVICE ROUTINES ON CLOSE UUO
OUT:: HRRZ T4,DEVSER(F) ;RESTORE T4
TLNN S,IO ;IS THIS DEVICE ALREADY DOING INPUT?
PUSHJ P,WAIT1## ;YES, WAIT TILL IT BECOMES INACTIVE
LDB T1,PIOMOD## ;GET DATA MODE SET BY INIT OR SETSTS.
CAIL T1,SD ;IS IT DUMP MODE(SD,DR,D)?
JRST OUTDMP ;YES.
PUSHJ P,OUTA ;NO, CHECK FOR NON-ZERO ADDRESS(USER
; CHANGING RING)
HLRZ U,DEVBUF(F) ;REL. ADDR. OF OUTPUT BUFFER HEADER
IFE FTVM,<
MOVEI T1,2(U) ;CHECK END OF 3 WORD HEADER
PUSHJ P,UADRCK
>
IFN FTVM,<
MOVEI T1,(U) ;START OF BUFFER HEADER
MOVEI T2,2(T1) ;TOP OF HEADER
PUSHJ P,LRNGE## ;MAKE SURE HEADER IS COMPLETELY IN CORE
>
IFN FTKA10,<
HRLI U,R ;SET INDEX FIELD FOR RELOCATION.
>
EXCTUX <SKIPG T2,@U> ; CHECK FIRST WORD OF BUFFER RING HEADER
JRST OUTF ;RING NOT SET UP OR FIRST REFERENCE TO RING
IFN FTVM,<
MOVEI T1,-1(T2) ;BUF LOC-1 IS STORED THERE
PUSHJ P,UADRCK ;ENSURE ADVBFF WONT FAULT
>
MOVEI T1,DEPOND ;ASYNCHRONOUS OUTPUT?
TLNN S,IOSTBL ;IF TROUBLE, BLUNDER ON TO RECOVERY REGARDLESS
TDNN T1,DEVAIO(F)
JRST OUT0 ;NO, PROCEED
HLL T2,U ;SET FOR RELOCATION
HRRZ T1,T2 ;ADR CHECK POINTER TO CURRENT BUF
PUSHJ P,UADRCK
EXCTUX <SKIPGE @T2> ;IS THE CURRENT BUFFER EMPTY
POPJ P, ;NO, RETURN
JRST OUTS ;YES, ADVANCE THE BUFFER HEADER
OUT0: TRNE S,IOACT ;ADR CHECK CURRENT BUFFER ONLY IF NOT I/O ACTIVE
JRST OUT1 ;BUFFER ALREADY ADDRESS CHECKED
HRRZ T1,DEVOAD(F) ;CURRENT BUFFER LOC DEVICE IS USING
PUSHJ P,UADRCK ;MAKE SURE IT'S LEGAL
IFN FTVM,<
PUSHJ P,BRNGE## ;MAKE SURE WHOLE BUFFER IS IN
EXCTUX <HRRZ T2,@U> ;OK - RESTORE T2
>
HRRZI T1,1(T2) ;PROCEED ONLY IF ADDR. OF WORD COUNT IN BOUNDS
CAIG T1,JOBPFI## ;IS 1ST ADR ABOVE JOB DATA AREA?
JRST ADRERR## ;NO, PRINT ERROR MESSAGE
OUT1: HLL T2,U ;SET TO RELOCATE
MOVE T1,DEVADV(F) ;IF BUFFERS SHOULDN'T BE DEADVANCED
TDNN T1,[DEPADV,,DEPOND] ; ON ERROR INTERCEPT OR DUE TO TROUBLE
AOSA U
JRST OUT3 ;THEN JUST START THE DEVICE
EXCTUX <HRRZ T1,@U> ;GET RH OF BYTE POINTER.
ADDI T2,1 ;REL. ADDR. OF 3RD WORD IN BUFFER.
JUMPE T1,OUT2 ;WRDCNT ALREADY STORED IF INTERCEPT RETRY
SUBI T1,(T2) ;DISTANCE FILLED BY USER.
TRNE S,IOWC
OUT2: EXCTUX <HRRZ T1,@T2>
SKIPGE T3,T1 ;PRESERVE USER'S WORDCOUNT
PJRST ADRERR## ;NEGATIVE WORDCOUNTS ARE ILLEGAL
MOVE T4,DEVMOD(F)
TLNE T4,DVDSK!DVDTA ;IF DISK OR DTA,
MOVEI T1,200 ; MAKE SURE WHOLE BUFFER IS THERE
PUSH P,T2 ;SAVE L(WRDCNT WORD)
IFN FTVM,<
EXCH T1,T2 ;FST ADR INTO T1
ADDI T2,(T1) ;TOP ADR IN T2
PUSHJ P,LRNGE## ;MAKE SURE WHOLE BUFFER IS OK
>
IFE FTVM,<
ADDI T1,(T2) ;FORM REL. ADR OF LAST WORD TO OUTPUT
PUSHJ P,UADRCK
>
LDB T1,PIOMOD ;I/O MODE
CAIE T1,BYTMOD ;BYTE MODE?
JRST OUT2A ;NO
EXCTUX <LDB T1,[POINT 6,@U,5]> ;POSITION FIELD OUT OF THE USER'S BYTE POINTER
MOVNS T1
ADDI T1,^D36 ;T1=36 - POSITION FIELD
SKIPGE T1 ;IF.LE.0, NO BYTES ARE STORED IN THIS WORD
MOVEI T1,0 ;0 BYTES IN THE LAST WORD
EXCTUX <LDB T4,[POINT 6,@U,11]> ;BYTE SIZE FROM USER'S BYTE POINTER
IDIVI T1,(T4) ;NUMBER OF BYTES IN THE LAST WORD
SOS T2,T3 ;OUT2 ROUNDED UP
MOVEI T3,^D36
IDIVI T3,(T4) ;NUMBER OF BYTES PER WORD
IMULI T3,(T2) ;NUMBER OF BYTES IN THE RECORD NOT COUNTING
; THE LAST WORD
ADDI T3,(T1) ;NUMBER OF BYTES IN THE RECORD
OUT2A: POP P,T2 ;GOOD-RESTORE T2
TRNN S,IOWC ;COMPUTE WORD COUNT FOR USER?
EXCTUU <HRRM T3,@T2> ;YES, STORE WORD COUNT IN 3RD WORD OF BUFFER.
SUBI U,1 ;REL. ADDR. OF 1ST WORD IN HEADER
; (POINTER TO CURRENT BUFFER).
SUBI T2,1 ;REL. ADDR. OF 2ND WORD IN BUFFER
IFN FTVM<
EXCTUX <HRRZ T1,@T2> ;START OF NEXT BUF
PUSH P,T2
PUSHJ P,UADRCK ;MAKE SURE ITS IN CORE
PUSHJ P,BRNGE##
POP P,T2
>
HRLZI T1,IOUSE ;FLAG CURRENT BUFFER CONTAINS ACTIVE DATA.
EXCTUU <IORB T1,@T2>
EXCTUU <HRRM T1,@U> ;ADVANCE CURRENT BUFFER ADDRESS
OUT3: MOVSI T1,DEPADV ;DON'T DEADVANCE BUFFERS BIT
ANDCAM T1,DEVADV(F) ;CLEAR BEFORE RETRY. REPEAT OF ERRORS
; WILL SET IT AGAIN.
MOVSI S,IOSTBL ;CLEAR TROUBLE FLAG
ANDCAB S,DEVIOS(F)
TRNN S,IOACT
PUSHJ P,CALOUT ;NO,START OUTPUT.
HLRZ U,DEVBUF(F) ;U TO REL. ADDR. OF BUFFER HEADER
IFN FTKA10,<
HRLI U,R ;SET TO RELOCATE
>
EXCTUX <MOVE T2,@U> ;T2 TO REL. ADDR. OF 2ND WORD OF BUFFER.
HRRZ T1,T2
PUSHJ P,UADRCK
HLL T2,U
MOVEI T1,@U ;IN CASE WE REDO THE UUO
EXCTUU <HLLZS 1(T1)> ; AFTER AN OFF-LINE INTERCEPT
EXCTUX <SKIPL @T2> ;HAS SERVICE ROUTINE EMPTIED NEXT BUFFER
; YET (USE BIT = 0)?
JRST OUTS ;YES RETURN TO USER
MOVEI T1,DEPAIO ;ASYNC IO?
TDNE T1,DEVAIO(F)
JRST OUT4 ;YES, DON'T BLOCK
PUSHJ P,WSYNC## ;NO - WAIT
TLZE S,IOSTBL ;ERROR OCCURED?
JRST OUT3 ;YES - TRY AGAIN
JRST OUTS ;RETURN TO USER.
OUT4: MOVEI T1,DEPOND ;INDICATE BUFFER HEADER NOT
IORM T1,DEVAIO(F) ;YES,, YET SET UP FOR NEXT OUTPUT
POPJ P, ;RETURN WITHOUT CLEARING ANYTHING
OUTF: TLO S,IO ;INDICATE OUTPUT FOR IOSETC
MOVEM S,DEVIOS(F) ;SAVE IN CASE OUTBUF CALLS CORE1
EXCTUX <SKIPE T2,@U>
JRST OUTF1
PUSHJ P,DFTNB ;GET DEFAULT NO OF BUFS
HRR M,T2
PUSHJ P,UOUTBF
HLRZ U,DEVBUF(F)
IFN FTKA10,<
HRLI U,R
>
OUTF1:
IFN FTVM,<
EXCTUX <HRRZ T1,@U> ;CALL BUFCLR EARLY
PUSHJ P,UADRCK ;IN CORE?
PUSHJ P,BRNGE##
MOVSI T2,DEPIBC ;USER DID AN OPEN WITH INHIBIT BUFFER CLEAR BIT
MOVSI T3,IOIBC ;INHIBIT CLEARING THIS BUFFER BIT
TDNE T2,DEVTYP(F) ;DID THE USER ENABLE FOR INHIBITING CLEARING BUFFER?
EXCTUX <TDNN T3,@U> ;YES, DOES HE WANT THIS BUFFER NOT TO BE CLEARED
CAIA ;NO, CLEAR R FROM THE LEFT HALF WORD IF ITS ON
JRST OUTF2
EXCTUX <HRRZ T1,@U>
PUSHJ P,BUFCLR ; TO ENSURE THAT A FAULT WONT HAPPEN
JRST ADRERR## ; AFTER THE VIRGIN-RING BIT IS CLEARED
>
OUTF2: HRLZI T1,IOUSE
EXCTUU <ANDCAB T1,@U> ;IOUSE:=0
HRRM T1,DEVOAD(F)
OUTS: EXCTUX <HRRZ T1,@U> ;CLEAR NEXT OUTPUT BUFFER.
MOVSI T2,DEPIBC ;USER DID AN OPEN WITH INHIBIT BUFFER CLEAR BIT
MOVSI T3,IOIBC ;INHIBIT CLEARING THIS BUFFER BIT
TDNE T2,DEVTYP(F) ;DID THE USER ENABLE FOR INHIBITING CLEARING BUFFER?
EXCTUX <TDNN T3,@U> ;YES, DOES HE WANT THIS BUFFER NOT TO BE CLEARED
CAIA ;NO, CLEAR R FROM THE LEFT HALF WORD IF ITS ON
JRST OUTS1 ;YES, SKIP CLEARING THE NEXT BUFFER
PUSHJ P,BUFCLR ;BEING CLEARED.
JRST ADRERR## ;ADDRESS CHECK
OUTS1: EXCTUX <HRRZ T2,@U>
HLL T2,U
EXCTUX <LDB J,[POINT 17,@T2,17]>
MOVEI T1,DEPOND ;CLEAR OUTPUT NOT YET DONE FLAG
ANDCAM T1,DEVAIO(F)
SOJA J,IOSETC
; ADDRESS+1
; JBFCTR:=(BUFFER SIZE-1)*[36/BYTE
; SIZE]
; RETURN TO USER'S PROGRAM
CALOUT::
MOVSI T1,DEPSIE ;BIT TO TEST
TDNN T1,DEVJOB(F) ;WANT TO LOOK FOR ERROR
JRST CALOU1 ;NO-PROCEED
MOVE T1,DEVIOS(F) ;YES - CHECK I/O STATUS
TRNE T1,742000 ;ANY ERRORS? (INCLUDE IOTEND)
POPJ P, ;RETURN (NO OUTPUT DONE)
CALOU1: IFN FTKI10!FTKL10,<
PUSHJ P,GTOEVM## ;GET EVM FOR THIS OUTPUT OPERATION
; IF THE DEVICE REQUIRES IT
>
MOVE T4,DEVSER(F) ;SETUP DISPATCH ADR. FOR SERVICE ROUTINE
PUSHJ P,DOU(T4) ;START DEVICE DOING OUTPUT
MOVE J,.CPJOB##(P4) ;RESTORE J
IFN FTKI10!FTKL10,<
MOVE S,DEVIOS(F) ;GET DEVICE STATUS
TRNN S,IOACT ;IS THE DEVICE I/O ACTIVE NOW?
PJRST RTEVMO## ;NO, RETURN ANY EXEC VIRTUAL MEMORY THE
; DEVICE MAY HAVE ASSIGNED
>
POPJ P, ;I/O ACTIVE, JUST RETURN
;HERE ON DUMP MODE INPUT
INDMP: MOVEI T1,DDI(T4) ;DISPATCH TO DO DUMP MODE INPUT
PJRST DMPIO ;JOIN COMMON INPUT/OUTPUT CODE
;HERE ON DUMP MODE OUTPUT
OUTDMP: MOVEI T1,DDO(T4) ;DISPATCH TO DO DUMP MODE OUTPUT
; AND FALL INTO COMMON INPUT/OUTPUT CODE
;ROUTINE TO SETUP FOR DUMP MODE I/O. IF THIS IS A
;CHANNEL DEVICE (DSK OR MTA) CALL THE SERVICE
;ROUTINE DIRECTLY AND MAPIO WILL FIXUP THE IOWDS AS NECESSARY. OTHERWISE,
;FIND THE LARGEST IOWD IN THE LIST, ALLOCATE ENOUGH EXEC VIRTUAL MEMORY
;TO COVER THAT IOWD, MAP THE FIRST IOWD, AND THEN CALL THE SERVICE ROUTINE
;TO START THE I/O
;CALLING SEQUENCE:
; MOVEI T1,DUMP I/O DISPATCH ADDRESS
; PUSHJ P,DMPIO
;NEVER RETURN IF ADDRESS CHECK
DMPIO: PUSHJ P,WSYNC## ;WAIT UNTIL THE DEVICE IS INACTIVE
PUSHJ P,DMPEV## ;GET EVM FOR THE I/O IF NEEDED
; IF KA10, JUST CHECK FOR LOOPS IN COMMAND LIST
PUSHJ P,(T1) ;CALL THE DEVICE ROUTINE TO START THE I/O
IFN FTKA10,<
PJRST WAIT1## ;WAIT UNTIL ITS DONE
>
IFN FTKI10!FTKL10,<
PUSHJ P,WAIT1## ;WAIT UNTIL ITS DONE
PJRST RTNEVM## ;RETURN ANY EVM JOB HAS FOR DOING I/O
>
;CALLING SEQUENCE:
; PUSHJ P,OUTA
; EXIT ALWAYS RETURNS HERE
;IF THE ADDRESS FIELD OF AC UUO IS ZERO,EXIT. OTHERWISE,CHECK IOACT.
;IF IOACT=1, WAIT FOR IOACT=0.
;SET JBFADR18-35:=ADDRESS FIELD OF AC UUO. JBFADR0:=1 AND EXIT.
OUTA:: TRNE M,-1 ;IS BUFFER ADDRESS SPECIFIED?
TLNE F,OCLOSB ;THIS OPTION DOESN'T APPLY DURING CLOSE UUO
POPJ P, ;NO
PUSHJ P,WAIT2
HLRZ U,DEVBUF(F)
IFN FTKA10,<
HRLI U,R
>
EXCTUU <HRRM M,@U>
HRRM M,DEVOAD(F)
HRLZI T1,IOUSE
EXCTUU <ANDCAM T1,@U>
POPJ P, ;RETURN
;RESDV.-- UUO TO RESET CHANNEL
;CALL: MOVE AC,CHANNEL
; RESDV. AC,
;ERROR IF NOT IMPLEMENTED, OR CHANNEL NOT OPEN(AC=-1)
;OK IF DONE
IFN FT5UUO,<
RESDV: JUMPL T1,RTM1 ;ERROR IF ILLEGAL CHANNEL
CAMLE T1,USRHCU## ;CHECK SIZE
JRST RTM1 ;ERROR
HRRZ P1,T1 ;SETUP CHANNEL NUMBER
MOVE F,USRJDA##(P1) ;SETUP DDB
JUMPE F,RTM1 ;IF NONE--RETURN ERROR
DPB P1,PUUOAC## ;PUT CHANNEL # IN AC FIELD OF M
; (IN CASE OF TROUBLE AND CALL HNGSTP)
PUSHJ P,RELEAC ;RESET IT
JRST CPOPJ1## ;SKIP RETURN
>
IFE FT5UUO,<RESDV==CPOPJ##>
SUBTTL RELEASE UUO
;RELEASE A DEVICE
RELEA1::
RELEA0:
RELEA2::RELEA3::
TRZ M,-1 ;CLOSE BOTH INPUT AND OUTPUT
PUSHJ P,CLOSE1
PUSHJ P,WAIT1## ;WAIT FOR DEVICE TO BECOME INACTIVE
RELEAC::HRRZ T4,DEVSER(F) ;RESTORE T4
RELEA5::PUSHJ P,DRL(T4) ;DISPATCH TO DEVICE SERVICE ROUTINE
MOVEI S,IOACT ;CLEAR IO ACTIVE BIT
ANDCAB S,DEVIOS(F) ;AND RETURN WITH S SET
LDB T2,IADPTR## ;GET COUNT OF NO OF CHANS DEVICE ON(IF DTA)
SOS T2 ;COUNT DOWN BY ONE
MOVE T1,DEVMOD(F)
TLNE T1,DVDTA ;DEVICE A DTA?
DPB T2,IADPTR## ;YES, STORE UPDATED COUNT
SETZB U,USRJDA##(P1) ;CLEAR DEVICE ASSIGNMENT
MOVE T1,USRHCU## ;HIGHEST IO CHANNEL IN USE
RELEA4: HRRZ T2,USRJDA##(T1)
JUMPN U,RELE4A ;NON-ZERO CHAN. ALREADY?
MOVE U,T2 ;NO, SET U WHEN FIRST(HIGHEST) FOUND
MOVEM T1,USRHCU## ;STORE HIGHEST IN USE CHANNEL
RELE4A: CAIE T2,(F) ;IS THIS DEVICE SAME AS ONE BEING RELEASED?
SOJGE T1,RELEA4
JUMPGE T1,CPOPJ## ;EXIT IF ON ANOTHER CHANNEL
;HERE FROM ERROR STOP ROUTINES (SWAP READ ERROR, PARITY ERROR, ETC.)
RELEA9::MOVSI T3,R
PUSHJ P,RTIEVM##
PUSHJ P,RTOEVM##
MOVEI T1,DEPAIO
ANDCAM T1,DEVAIO(F) ;CLEAR NON-BLOCKING I/O FLAG
IFE FTDISK,<
MOVE T1,DEVNAM(F) ;IS THIS SYSTEM TAPE?
CAME T1,SYSTAP##
JRST RELEA7 ;IS DISK OR NOT SYSTEM TAPE
SKIPN STUSER## ;HAS COUNT ALREADY BEEN REDUCED AT ESTOP?
JRST RELEA7 ;YES
SETZM STUSER## ;YES, CLEAR SYSTEM USER NO.
SOSL STREQ## ;YES, REDUCE COUNT
SETOM STAVAL## ;SOMEONE IS WAITING, SET AVAILABLE FLAG
>
RELEA7::MOVEI T2,ASSPRG ;CLEAR ASSIGNED BY PROGRAM BIT
RELEA6::ANDCAB T2,DEVMOD(F) ;CALLED FROM DEASSIGN
TRZ T2,777 ;CLEAR JOB NO. FIELD
TLNE T2,DVDSK+DVMTA ;DSK?
DPB T2,PINBFN## ;YES, CLEAR NO OF BUFS
TDNE T2,[XWD TTYATC,ASSCON+ASSPRG]
POPJ P, ;DEVICE ASSIGNED BY OTHER MEANS TOO
SETZM DEVBUF(F) ;NO BUFFER HEADERS
IFN FTPI,<
SETZM DEVPSI(F) ;CLEAR PSI CONDITIONS
>
PUSHJ P,CLRDVL ;DISCONNECT JOB FROM DDB
MOVE T2,DEVMOD(F) ;PUT DEVMOD IN T2
IFN FTMTSET,<
TLNN T2,DVTTY ;DON'T BE FOOLED BY NULL
TLNN T2,DVMTA
JRST RELE6A
HRRI T2,MTSIZ##+1 ;GET DEFAULT MTA BLOCK SIZE
DPB T2,PBUFSZ## ; SET SYSTEM DEFAULT IN BUFFER
TRZ T2,-1 ;CLEAR FOR DENSITY
DPB T2,TDYDN1## ; SET TO FORCE INSTALLATION DENSITY
DPB T2,PBUFRM## ;CLEAR FRAME-COUNT
RELE6A:> ;END CONDITIONAL ON FTMTSET
IFN FTNET,<
MOVSI T1,DVCNET ;CHECK FOR A NETWORK DEVICE
TDNE T1,DEVCHR(F) ;IS IT
PJRST ZAPNET## ;YES, CLEAR THE DDB
>;END FTNET
IFN FTDISK,<
IFN FTSPL,<
SKIPL DEVSPL(F) ;IS DEVICE A SPOOLED DISK
>
TLNE T2,DVDSK ;IS DEVICE A DSK
PJRST CLRDDB## ;YES-RETURN DDB TO STORAGE
> ;END IFN FTDISK
IFN FTMSGSER,<
LDB T2,PDVTYP## ;GET THE DEVICE TYPE
CAIN T2,.TYMPX/.TYEST;IS THIS AN MPX DDB?
PUSHJ P,ZAPMPX## ;YES--KILL IT OFF
> ;END FTMSGSER
PJRST XTKLDB## ;GO KILL XTC DDB IF NECESSARY
SUBTTL STATUS SETTING AND GETTING UUO'S
;CALLING SEQUENCE
; STATO D,MASK
; EXIT1 ALL SELECTED BITS ARE 0
; EXIT2 SOME SELECTED BITS ARE 1
;TESTS BITS OF I/O STATUS WORD OF DEVICE ON USER'S CHANNEL D WHICH
;ARE SELECTED BY MASK.
USTATO::
IFN FTXTC,<
PUSHJ P,XTCIOS## ;GET S
>
TRNE S,(M) ;SKIP IF ANY INDICATED BITS ARE ONE
AOS (P)
POPJ P, ;RETURN TO USER
;CALLING SEQUENCE
; STATUS D,ADR
; EXIT ALWAYS RETURNS HERE
;STORES I/O STATUS WORD OF DEVICE ON CHANNEL D IN LOCATION ADR.
USTATS::
IFN FTXTC,<
PUSHJ P,XTCIOS## ;GET S
>
HRRZ T1,S ;GET USER HALF OF IOS.
PJRST PUTWDU## ;ADDRESS CHECK AND STORE IN USER AREA
;CALLING SEQUENCE
; STATZ D,MASK
; EXIT1 SOME SELECTED BITS ARE 1
; EXIT2 ALL SELECTED BITS ARE 0
;TESTS BITS OF I/O STATUS WORD OF DEVICE ON USER'S
;CHANNEL D WHICH ARE SELECTED BY MASK.
USTATZ::
IFN FTXTC,<
PUSHJ P,XTCIOS## ;GET S
>
TRNN S,(M) ;SKIP IF ALL INDICATED BITS ARE ZERO
AOS (P)
POPJ P, ;RETURN TO USER
;IN UUO - LIKE INPUT SKIPS IF EOF OR ERRORS OR BUFFER NOT FULL IF NON-BLOCKING I/O
TIN:: PUSHJ P,UIN00 ;DO INPUT UUO
MOVEI T1,DEPIND ;INPUT NOT YET DONE?
TRNN S,IOBKTL+IODTER+IODERR+IOIMPM+IODEND
TDNE T1,DEVAIO(F)
AOS JOBPD1##(R)
IFE FTPI,<
POPJ P,
>
IFN FTPI,<
JRST IOPTST
>
;OUT UUO - LIKE OUTPUT - SKIPS IF ERRORS OR NO EMPTY BUFFER IF NON-BLOCKING I/O
TOUT:: PUSHJ P,UOUT00 ;DO OUTPUT UUO
MOVEI T1,DEPOND ;OUTPUT NOT YET DONE?
TRNN S,IOBKTL+IODTER+IODERR+IOIMPM+IOTEND
TDNE T1,DEVAIO(F)
AOS (P)
IFE FTPI,<
POPJ P,
>
IFN FTPI,<
IOPTST: MOVE J,.C0JOB##
XCT OKSGNL## ;NO, HAVE PSISER
POPJ P, ;NOPE
TLNE S,IO ;GET THE DIRECTION BIT
PJRST PSIODN## ;OUTPUT
PJRST PSIIDN## ;INPUT
>
;5 UUOS FOR EACH INSTALLATION TO DEFINE
;OPCODES 42-46
SUBTTL ROUTINES TO ADVANCE BUFFERS
;ROUTINE TO ADVANCE OUTPUT BUFFER AT INTERRUPT LEVEL
;CALL: PUSHJ P,ADVBFE
; EXIT1 RETURN IF NEXT BUFFER IS EMPTY
; EXIT2 RETURN IF NEXT BUFFER IS FULL
;CLEARS THE USE BIT (IOUSE:=0) OF THE BUFFER POINTED TO BY THE
;OUTPUT BUFFER ADDRESS (DEVOAD) OF THE CURRENT DEVICE DATA BLOCK
;AND ADVANCES THE BUFFER ADDRESS TO THE NEXT BUFFER IN THE RING.
;UPON RETURN, SKIPS IF THE NEXT BUFFER IS FULL.
;SECOND WORD OF NEXT BUFFER IS ADDRESS CHECKED TO
;MAKE SURE IT IS NOT IN JOB DATA AREA OR ABOVE USER AREA
;THE SECOND WORD OF CURRENT BUFFER WAS CHECKED AT UUO LEVEL
;OR PREVIOUS CALL TO ADVBFE
ADVBFE::MOVE T1,DEVOAD(F) ;USER OR EXEC VIRTUAL ADDRESS OF CURRENT BUFFER
TRNN T1,-1 ;HAS IT BEEN CLEARED BY A RELEASE?
POPJ P, ;YES, GIVE STOP I/O RETURN
IFN FTKI10!FTKL10,<
PUSHJ P,SVEUF## ;PUSH THE USER BASE REGISTER AND SETUP UBR
; SO THAT CURRENT USER IS ADDRESSABLE
>
IFN FTMSGSER,<
MOVEI T2,DEPMSG ;IS THIS DEVICE CONTROLLED BY
TDNE T2,DEVMSG(F) ; BY MSGSER
PJRST MSGBFE## ;YES--GO ADVANCE THINGS
>
PUSH P,T3 ;ITS POSSIBLE THAT SOME DEVICE ROUTINES
; DEPEND ON T3 BEING INTACT ON RETURN
MOVSI T3,IOUSE ;SET TO TURN OFF THE USE BIT
IFN FTKI10!FTKL10,<
HRRZ T2,DEVEVM(F) ;IS THIS BUFFER MAPPED BY THE EXEC MAP?
JUMPE T2,ADVBE1 ;JUMP IF NOT A MAPPED ADDRESS
MOVEM S,-1(T1) ;THE BUFFER IS ADDRESSABLE - STORE IOS
ANDCAB T3,(T1) ;GET THE SIZE AND ADDRESS OF THE NEXT BUFFER
; AND CLEAR THE USE BIT
IFN FTMS&FTKL10,<
PUSHJ P,KLBUFM ;GET BUF ENDS OUT OF CACHE
>
IFN FTVM,<
HRRZ T1,T3 ;ADDRESS OF START OF BUFFER
PUSHJ P,IADCKL ;MAKE SURE ITS LEGAL (MIGHT BE PAGED OUT)
JRST ADVBU2 ;ILLEGAL ADDRESS (ADR CHECK)
HRLM T3,DEVEVM(F) ;LEGAL ADR, SAVE AS NEXT BUFFER LOC
PUSHJ P,BADCK ;IS WHOLE BUFFER LEGAL AND IN CORE?
JRST ADVBU2 ;NO, STOP IO
>
IFE FTVM,<
PUSHJ P,BADCK ;ADDRESS CHECK THE NEXT BUFFER
JRST ADVBU2 ;OUT OF BOUNDS - GIVE STOP I/O RETURN
>
PUSHJ P,ADVEVM## ;ADVANCE THE BUFFER IN EXEC VIRTUAL MEMORY
JRST ADVBU2 ;NOT ENOUGH PAGES TO COVER THE NEXT BUFFER
; UUO LEVEL WILL ALLOCATE MORE ON THE NEXT UUO
DPB T1,PDVOAD## ;STORE THE EXEC VIRTUAL ADDRESS OF THE NEXT
; BUFFER FOR THE DEVICE ROUTINE
SKIPL (T1) ;IS THE NEXT BUFFER AVAILABLE? (USE BIT ON)
JRST ADVBU2 ;NO, GIVE STOP I/O RETURN
JRST ADVBU1 ;GO CHECK FOR OTHER REASONS I/O SHOULD BE STOPPED
>
ADVBE1:
;HERE TO ADVANCE A BUFFER WHICH IS NOT MAPPED BY THE EXEC MAP
IFN FTKA10,<
MOVEI T1,@T1 ;RELOCATE THE BUFFER ADDRESS
>
EXCTXU <MOVEM S,-1(T1)>
EXCTUU <ANDCAB T3,(T1)>;CLEAR THE USE BIT AND GET THE SIZE AND
; ADDRESS OF THE NEXT BUFFER
IFN FTMS&FTKL10,<
PUSHJ P,KLBUF ;GET BUFFER END OUT OF CACHE
>
IFN FTVM,<
HRRZ T1,T3 ;ADDRESS OF START OF BUFFER
PUSHJ P,IADCKL ;MAKE SURE ITS LEGAL (MIGHT BE PAGED OUT)
JRST ADVBU3 ;ILLEGAL ADDRESS (ADR CHECK)
HRRM T3,DEVOAD(F) ;LEGAL ADR, SAVE AS NEXT BUFFER LOC
PUSHJ P,BADCK ;IS WHOLE BUFFER LEGAL AND IN CORE?
JRST ADVBU3 ;NO, STOP IO
>
IFE FTVM,<
PUSHJ P,BADCK ;ADDRESS CHECK THE NEXT BUFFER
JRST ADVBU3 ;OUT OF BOUNDS - GIVE STOP I/O RETURN
HRRM T3,DEVOAD(F) ;STORE USER VIRTUAL ADDRESS OF NEXT BUFFER
; FOR THE DEVICE ROUTINE
>
IFN FTKA10,<
ADDI T3,(R) ;KA10 - RELOCATE BUFFER ADDRESS
>
EXCTUX <SKIPL (T3)> ;NEXT BUFFER AVAILABLE?
JRST ADVBU3 ;NO, GIVE STOP I/O RETURN
JRST ADVBU1 ;YES, CHECK FOR OTHER REASONS WHY I/O SHOULD STOP
;ROUTINE TO ADVANCE INPUT BUFFER AT INTERRUPT LEVEL
;CALL: PUSHJ P,ADVBFF
; EXIT1 RETURN IF NEXT BUFFER IS FULL
; EXIT2 RETURN IF NEXT BUFFER IS EMPTY
;SETS THE USE BIT (IOUSE:=1) OF THE BUFFER POINTED TO BY THE
;INPUT BUFFER ADDRESS (DEVIAD) OF THE CURRENT DEVICE DATA BLOCK
;AND ADVANCES THE BUFFER ADDRESS TO THE NEXT BUFFER IN THE RING.
;UPON RETURN, SKIPS IF THE NEXT BUFFER IS EMPTY.
;SECOND WORD OF NEXT BUFFER IS ADDRESS CHECKED TO MAKE SURE
;IT IS NOT IN IO PROTECTED PART OF JOB DATA AREA OR ABOVE
;USER AREA
;ALSO END OF BUFFER IS CHECKED TO MAKE SURE NOT ABOVE JOB AREA
ADVBFF::MOVE T1,DEVIAD(F) ;USER OR EXEC VIRTUAL ADDRESS OF CURRENT BUFFER
TRNN T1,-1 ;HAS IT BEEN CLEARED BY A RELEASE?
POPJ P, ;YES, GIVE STOP I/O RETURN
IFN FTKI10!FTKL10,<
PUSHJ P,SVEUF## ;PUSH THE USER BASE REGISTER AND SETUP UBR
; SO THAT CURRENT USER IS ADDRESSABLE
>
PUSH P,T3 ;ITS POSSIBLE THAT SOME DEVICE ROUTINES
; DEPEND ON T3 BEING INTACT UPON RETURN
IFN FTMSGSER,<
MOVEI T2,DEPMSG ;IF THIS DEVICE IS CONTROLLED
TDNE T2,DEVMSG(F) ; VIA MSGSER. SHUT IT DOWN NOW
JRST ADVBU2 ; SINCE NEXT BUFFER MAY HAVE I/O TOO
>
MOVSI T3,IOUSE ;SET TO TURN ON THE USE BIT
IFN FTKI10!FTKL10,<
HRRZ T2,DEVEVM(F) ;IS THE BUFFER MAPPED BY THE EXEC MAP?
JUMPE T2,ADVBF1 ;JUMP IF NOT A MAPPED ADDRESS
MOVEM S,-1(T1) ;THE BUFFER IS ADDRESSABLE - STORE IOS
IORB T3,(T1) ;GET THE SIZE AND ADDRESS OF THE NEXT BUFFER
; AND TURN ON THE USE BIT
TLZ T3,IOUSE ;CLEAR THE USE BIT FOR ADVEVM
IFN FTKL10&FTMS,<
PUSHJ P,KLBUFM ;REMOVE BUFFER ENDS FROM CACHE
>
IFN FTVM,<
HRRZ T1,T3 ;ADDRESS OF START OF BUFFER
PUSHJ P,IADCKL ;MAKE SURE ITS LEGAL (MIGHT BE PAGED OUT)
JRST ADVBU2 ;ILLEGAL ADDRESS (ADR CHECK)
HRLM T3,DEVEVM(F) ;LEGAL ADR, SAVE AS NEXT BUFFER LOC
PUSHJ P,BADCK ;IS WHOLE BUFFER LEGAL AND IN CORE?
JRST ADVBU2 ;NO, STOP IO
>
IFE FTVM,<
PUSHJ P,BADCK ;ADDRESS CHECK THE NEXT BUFFER
JRST ADVBU2 ;OUT OF BOUNDS - GIVE STOP I/O RETURN
>
PUSHJ P,ADVEVM## ;ADVANCE THE BUFFER IN EXEC VIRTUAL MEMORY
JRST ADVBU2 ;NOT ENOUGH PAGES TO COVER THE NEXT BUFFER
; UUO LEVEL WILL ALLOCATE MORE ON NEXT UUO
DPB T1,PDVIAD## ;STORE THE EXEC VIRTUAL ADDRESS OF THE NEXT
; BUFFER FOR THE DEVICE ROUTINE
SKIPGE (T1) ;IS THE NEXT BUFFER AVAILABLE? (USE BIT OFF)
JRST ADVBU2 ;NO, GIVE STOP I/O RETURN
JRST ADVBU1 ;GO CHECK FOR OTHER REASONS I/O SHOULD BE STOPPED
>
ADVBF1:
;HERE TO ADVANCE A BUFFER WHICH IS NOT MAPPED BY THE EXEC MAP
IFN FTKA10,<
MOVEI T1,@T1 ;RELOCATE THE BUFFER ADDRESS
>
EXCTXU <MOVEM S,-1(T1)>
EXCTUU <IORB T3,(T1)>;TURN ON THE USE BIT AND GET THE ADDRESS
; AND SIZE OF THE NEXT BUFFER
IFN FTKL10&FTMS,<
PUSHJ P,KLBUF ;REMOVE BUFFER END FROM CACHE
>
IFN FTVM,<
HRRZ T1,T3 ;ADDRESS OF START OF BUFFER
PUSHJ P,IADCKL ;MAKE SURE ITS LEGAL (MIGHT BE PAGED OUT)
JRST ADVBU3 ;ILLEGAL ADDRESS (ADR CHECK)
HRRM T3,DEVIAD(F) ;LEGAL ADR, SAVE AS NEXT BUFFER LOC
PUSHJ P,BADCK ;IS WHOLE BUFFER LEGAL AND IN CORE?
JRST ADVBU3 ;NO, STOP IO
>
IFE FTVM,<
PUSHJ P,BADRCK ;ADDRESS CHECK THE NEXT BUFFER
JRST ADVBU3 ;OUT OF BOUNDS, GIVE STOP I/O RETURN
HRRM T3,DEVIAD(F) ;STORE THE USER VIRTUAL ADDRESS OF THE
; NEXT BUFFER FOR THE DEVICE ROUTINE
>
IFN FTKA10,<
ADDI T3,(R) ;RELOCATE BUFFER ADDRESS
>
EXCTUX <SKIPGE (T3)> ;IS THE BUFFER EMPTY?
JRST ADVBU3 ;NO, GIVE STOP I/O RETURN
;HERE TO SEE IF I/O SHOULD BE STOPPED SO JOB CAN BE SHUFFLED,
; SWAPPED, LOCKED, OR THE USER HAS TYPED CONTROL C
ADVBU1::LDB T2,PJOBN## ;GET JOB NUMBER OF JOB I/O IS BEING DONE FOR
SKIPGE T2,JBTSTS##(T2) ;IS THE JOB RUNNABLE?
TLNE T2,SHF!CMWB!CNTRLC
JRST ADVBU2 ;NO, GIVE STOP I/O RETURN
IFN FTLOCK,<
TRNN T2,LOK ;TRYING TO LOCK THE JOB IN CORE?
>
TRNE S,IOCON ;OR DISCONTINUOUS MODE I/O?
JRST ADVBU2 ;YES, SHUT DOWN THE I/O
AOSA -1(P) ;SET SKIP (CONTINUE I/O) RETURN
ADVBU2: PUSHJ P,RTNEVM## ;SHUTTING DOWN I/O, GIVE BACH ANY EVM
ADVBU3:
IFN FTKL10&FTMS,<
PUSHJ P,OUCHE##
>
POP P,T3 ;RESTORE T3
POPJ P, ;GIVE STOP OR CONTINUE I/O RETURN
;ROUTINE TO ADDRESS CHECK A BUFFER
;CALLING SEQUENCE:
; MOVE T3,USER VIRTUAL BUFFER ADDRESS
; PUSHJ P,BADRCK
; RETURN HERE ON ADDRESS CHECK
; RETURN HERE IF BUFFER IS OK
;PRESERVES T3
BADCK:
BADRCK::
IFE FTVM,<
MOVEI T1,-1(T3) ;T1 = ADDRESS OF WORD -1 OF BUFFER
PUSHJ P,IADRCK ;ADDRESS CHECK THAT
POPJ P, ;OUT OF BOUNDS
HRRZ T2,T3
IFN FTKA10,<
TLO T2,R ;RELOCATE KA10 STYLE
>
EXCTUX <HLRZ T2,@T2> ;T2=NUMBER OF WORDS IN THE BUFFER
TRZ T2,IOUSE ;ZERO THE USE BIT
ADDI T1,1(T2) ;T1 = ADDRESS OF LAST WORD IN THE BUFFER
PJRST IADRCK ;ADDRESS CHECK THAT
>
IFN FTVM,<
HRRZ T1,T3 ;T1=ADDRESS OF FIRST WORD IN THE BUFFER
PUSHJ P,IADRCK ;IN-CORE AND LEGAL?
POPJ P, ;NO
EXCTUX <HLRZ T2,(T1)> ;SIZE
TRZ T2,IOUSE
ADDI T2,(T1) ;TOP OF BUFFER
SOJA T1,ZRNGE## ;LET VMSER CHECK THE LIMITS
>
IFN FTMS&FTKL10,<
;SUBROUTINE TO FIX UP A BUFFER WITH RESPECT TO CACHE INSURES THAT
; THE END POINTS OF A BUF ARE OUT OF CACHE
;ENTER T1=ADDR OF BUFFER (CALL KLBUFM IF IN EVM)
;PRESERVES T3
KLBUFM: SKIPA T4,1(T1) ;GET WORD COUNT
KLBUF: TDZA T4,T4 ;CHAN DEV-DON'T WORRY ABOUT TOP
ADDI T4,1(T1) ;POINT TO END OF BUFFER
PUSHJ P,OUCHE## ;CHASE FROM CACHE
TRNN T1,3 ;S - WORD IN SAME LINE?
SOJA T1,.-2 ;NO, CHASE PREVIOUS LINE
SKIPE T1,T4 ;IF CPU HAS TOP OF BUF IN CACHE
PJRST OUCHE## ;REMOVE TOP LINE AND RETURN
POPJ P, ;CHAN DEV-DOESN'T HAVE LOC IN CACHE
>
;ROUTINE TO ADDRESS CHECK AT UUO LEVEL ONLY
;CALL HRRZ T1,REL ADR.
; PUSHJ P,UADCK1
; NEVER RETURNS IF ERROR,STOPS JOB AND PRINTS ERROR
;BAD ADR. IF IN LOC 20-JOBPFI IN JOB DATA AREA
;OR IF ABOVE PROTECTION(USRREL) FOR CURRENT JOB
UADCK1::TRNN T1,777760 ;IN USER ACS?
POPJ P, ;YES, ADDRESS IS OK
;ROUTINE TO ADDRESS CHECK AT UUO LEVEL ONLY
;USER ACS ARE ALSO ILLEGAL(ADR IS FOR IO USE LATER AT
;INTERRUPT LEVEL)
;CALL: HRRZ T1,REL.ADR.
; PUSHJ P,UADRCK
; NEVER RETURN IF ERROR
UADRCK::CAILE T1,JOBPFI## ;IS ADR. IN IO PROT. PART OF JOB DATA AREA?
CAMLE T1,USRREL## ;NO, IS IT ABOVE PROTECT.?
JRST ADRERR## ;YES, STOP JOB AND PRINT ERROR
IFE FTVM,<
POPJ P, ;NO
>
IFN FTVM,<
PUSHJ P,FLTST## ;NO, IS PAGE IN CORE?
PJRST UUOFLT## ;NOT THERE, CALL PAGE FAULT HANDLER
CAML T1,.UPMP+.UPHSS ;NO PAGE FAULT - IS IT IN THE LOW SEG?
CAML T1,.UPMP+.UPHSE
POPJ P, ;YES, OK
PJRST ADRERR## ;NO, ADDRESS CHECK
>
;ROUTINE TO ADDRESS CHECK AT ANY LEVEL
;CALL: MOVE R,[XWD PROT.,RELOC,]
; HRRZ T1,REL. ADR.
; PUSHJ P,IADRCK
; ERROR RETURN(ERROR MESSAGE NOT PRINTED,JOB NOT STOPPED)
; OK RETURN
IADRCK::
IFN FTVM,<
PUSHJ P,FLTST## ;MAKE SURE IN CORE
POPJ P, ;ITS NOT
>
IADCKL: MOVS T2,R ;GET PROTECTION(TO RH)
CAILE T1,JOBPFI## ;ADR. ABOVE PROT. PART OF JOB DATA AREA?
CAILE T1,(T2) ;YES, BELOW OR EQUAL TO PROTECT.?
POPJ P, ;NO
IFN FTVM,<
CAML T1,.UPMP+.UPHSS
CAML T1,.UPMP+.UPHSE ;MAKE SURE PAGE IS IN LOW SEGMENT
>
AOS (P) ;IT IS, SKIP
POPJ P, ;RETURN
;SUBROUTINE TO ADDRESS CHECK AN ASCIZ STRING IN A USER'S ADDRESS SPACE
;CALLING SEQUENCE:
; MOVE T1, BYTE POINTER TO STRING (LH=-1 IF LEFT JUSTIFIED STRING)
; PUSHJ P,CKSTR
;DOESN'T RETURN IF A PAGE FAULT WOULD OCCUR, RETURNS CPOPJ ON AN
; ADDRESS CHECK, CPOPJ1 IF OK TO REFERENCE THE STRING, T1=
; BYTE POINTER TO THE STRING
;PRESERVES T2-T4
CKSTR:: PUSHJ P,SAVE4## ;SAVE P1-P3
MOVEI P4,200 ;DON'T LET SOME TURKEY MAKE US LOOP TOO LONG
HLRE P1,T1 ;LEFT HALF OF THE BYTE POINTER
AOSN P1 ;IS IT -1?
HRLI T1,(POINT 7,0) ;YES, MAKE IT A POINTER TO A LEFT JUSTIFIED STRING
PUSH P,T1 ;SAVE THE BYTE POINTER
PUSH P,M ;AND M
HRRI M,-1(T1) ;SETUP M TO FETCH THE STRING
MOVEI P1,44 ;SETUP ROTATE OFFSET
LDB P2,[POINT 6,T1,5] ;GET RESIDUE
SUB P1,P2
IDIVI P2,7 ;NUMBER OF BYTES IN THE FIRST WORD
PUSHJ P,GETWR1## ;GET THE FIRST WORD
JRST CKSTR4 ;ADDRESS CHECK
LSH T1,(P1) ;LEFT JUSTIFY FIRST BYTE
JRST CKSTR2 ;CHECK IT
CKSTR1: MOVEI P2,5 ;FIVE BYTES PER WORD
PUSHJ P,GETWR1## ;GET THE NEXT WORD
JRST CKSTR4 ;ADDRESS CHECK
CKSTR2: TLNN T1,(177B6) ;A NULL BYTE?
JRST CKSTR3 ;YES, STRING IS OK
LSH T1,7 ;LEFT JUSTIFY THE NEXT BYTE
SOJG P2,CKSTR2 ;JUMP IF MORE BYTES IN THIS WORD
SOJG P4,CKSTR1 ;GET NEXT WORD. IS STRING LONG?
PUSHJ P,SCDCHK##
MOVEI P4,200 ;THEN RESUME FOR ANOTHER
JRST CKSTR1 ;FRAGMENT
CKSTR3: AOS -2(P) ;SKIP RETURN
CKSTR4: POP P,M ;RESTORE M
JRST TPOPJ## ;RESTORE BYTE POINTER AND RETURN
SUBTTL DUMP MODE COMMAND LIST PROCESSING ROUTINES
;ROUTINE TO SCAN A DUMP MODE COMMAND LIST
;AND FIND THE NEXT IO COMMAND WORD. THE LIST
;CONSISTS OF IOWD FORMAT WORDS (LH=NEGATIVE
;WORD COUNT-RH=ADDRESS OF FIRST WORD MINUS 1) AND
;GO TO WORDS (LH=ANY POSITIVE VALUE-RH=ADDRESS
;OF NEXT GO TO WORD OR IOWD). THE LIST IS
;TERMINATED BY A WORD OF ALL BINARY ZEROES. WHERE
;NO GO TO WORD INTERVENES, THE WORDS OF A LIST
;OCCUPY SEQUENTIAL MEMORY LOCATIONS. TO PREVENT
;LOOPING IN THIS ROUTINE, A MAXIMUM OF 3 SUCCESSIVE GO TO
;WORDS IS PERMITTED BE FOUND BEFORE AN IOWD MUST BE
;THIS ROUTINE IS CALLED AT UUO AND INTERRUPT LEVELS
;CALL: MOVE M,[XWD R,RELATIVE ADDRESS OF FIRST COMMAND]
; PUSHJ P,COMCHK
;THIS ENTRY (COMCHK) SHOULD ONLY BE USED THE
;FIRST TIME THE ROUTINE IS CALLED FOR A PARTICULAR
;DUMP IO REQUEST. IT SETS UP THE BOUNDARY VALUES
;FOR SUBSEQUENT ADDRESS CHECKS AND MUST BE
;CALLED AT UUO LEVEL
;SUBSEQUENT CALLS: SET M=TO ADDRESS OF LAST COMMAND EXECUTED
;(AS RETURNED BY PREVIOUS CALL TO THIS ROUTINE)
; PUSHJ P,NXCMR
;RETURN FROM BOTH CALLS IS TO CALL +1
;WITH ACCUMULATORS SET AS FOLLOWS:
;(T2)=USER UPPER LIMIT (SET BY COMCHK-MUST BE SET UP BEFORE CALLING NXCMR)
;(T3)=USER LOWER LIMIT (SET BY COMCHK-MUST BE SET UP BEFORE CALLING NXCMR)
;(M)=ADDRESS OF IOWD FOR NEXT DUMP MODE IO OPERATION
;(T1)=THE IOWD ITSELF OR 0 IF END OF LIST
;(S)=0 IF NO ERROR, -1 IF AN ERROR
;ERRORS ARE: IO OUTSIDE THE USER'S AREA
; MORE THAN 3 GO TO WORDS (LH .GE. 0) IN SUCCESSION
; COMMAND LIST OUTSIDE THE USER'S AREA
; (COMMANDS MAY BE IN AC'S, BUT IO TO
; AC'S IS ILLEGAL
;AC'S CLOBBERED: S,T1,T2,T3,M
;USED BUT RESTORED: P1,P2,P3
COMCHK::MOVEI T3,JOBPFI## ;HIGHEST PROTECTED LOCATION IN JOBDAT
SKIPGE USRHCU## ;IS A SAVE OR GET IN PROGRESS?MAY BE RUN UUO
MOVEI T3,JOBSAV## ;YES. USE HIGHEST LOCATION NOT WRITTEN BY SAVE
SOS M ;BACK UP POINTER-IT WILL BE INCREMENTED
HLRZ T2,R ;HIGHEST USER LOCATION
NXCMR:: PUSHJ P,SAVE4## ;SAVE P1-P4
LDB P4,PJOBN## ;P4=JOB NUMBER OF JOB DOING I/O
EXCH P4,J ;SAVE J IN P4 AND PUT THE JOB NUMBER IN J
IFN FTKI10!FTKL10,<
PUSHJ P,SVEUB## ;MAKE THE JOB ADDRESSABLE
MOVEI T1,JS.ASA ;FLAG SAYING MEMORY REFERENCES TO USER 0-17
TDNE T1,JBTSTS##(J) ; ARE TO SHADOW AC'S - IS IT ON?
TLO J,400000 ;YES, REMEMBER THAT
MOVEI T1,(J) ;PICK UP THIS JOB'S NUMBER
CAME T1,.C0JOB## ;IS IT THE ONE WE'RE RUNNING
PUSHJ P,SETASA## ;NO, FLAG REFERENCES TO USER 0-17 AS SHADOW
; AC REFERENCES
>
HRREI P1,-3 ;ALLOW A MAXIMUM OF 3 GO TO WORDS
PUSH P,T2 ;SAVE HIGHEST USER LOCATION
AOSA T1,M ;POINT TO THE NEXT OR FIRST IOWD
NXCMRA: HRRM T1,M ;GET NEXT COMMAND IF THIS ONE IS A GOTO WORD
PUSHJ P,GETWRD## ;GET THE IOWD
JRST NXBAD ;ADDRESS CHECK
JUMPE T1,NXCOK ;IF 0, ITS THE LIST TERMINATOR
TLNE T1,-1 ;A GOTO WORD ?
JRST NXCHIT ;NO, A REAL IOWD, GO CHECK IT
AOJLE P1,NXCMRA ;YES, ITS A GOTO WORD
NXBAD: MOVEI S,-1 ;FLAG BAD COMMAND
TDZA T1,T1 ;ZERO T1 AS IF THE LIST HAD TERMINATED
NXCOK: MOVEI S,0 ;THE IOWD IS OK
IFN FTKI10!FTKL10,<
SKIPL J ;WAS JS.ASA FLAG ON?
PUSHJ P,CLRASA## ;NO, CLEAR SHADOW AC REFERENCE FLAG
>
MOVE J,P4 ;RESTORE J
JRST NXOUT ;EXIT WITH T1, M AND S SET TO SHOW
;RESULTS. IF CALL WAS TO COMCHK,T2 & T3 ALSO SET
;TO USER BOUNDARIES. ALWAYS EXIT TO CALL +1
NXCHIT:
IFN FTEXE,<JUMPL J,NXCOK ;TRUCT COMCON IF SAVE IN PROGRESS
; DON'T ADDRESS-CHECK
>;END IFN FTEXE
HRRZ P2,T1 ;THIS IS IOWD OR GO TO NOT POINTING TO AC
HLRO P3,T1 ;SAVE ADDRESS POINTED TO AND NEGATIVE COUNT
CAMG P2,T3 ;IS START ABOVE PROTECTED AREA?
JRST NXBAD ;NO. REPORT ERROR
MOVMS P3 ;WORD COUNT
ADD P2,P3 ;END OF IO
IFN FTEXE,<
SKIPGE JOBHCU##(R) ;IF SAVE N IN PROGRESS,
TLZ P2,-1 ; SUPPRESS CARRY IF ADR=-1
>
CAMLE P2,(P) ;END OF IO ABOVE USER UPPER LIMIT?
JRST NXBAD ;YES, IO WOULD RUN PAST END OF USER AREA
IFN FTVM,<
SKIPGE JOBHCU##(R) ;SAVE IN PROGRESS?
JRST NXCOK ;YES, IOWD LIST IS OK
MOVE T2,P2 ;TOP ADR FOR IO
MOVE P2,T1 ;PRESERVE T1
MOVEI T1,1(T1) ;START ADR FOR IO
PUSHJ P,ZRNGE## ;ALL PAGES IN CORE?
JRST NXBAD ;NO, USER FIDDLED WITH HIS LIST
; (LIST WAS CHECKED BEFORE IO STARTED - WAS OK THEN)
MOVE T1,P2 ;YES, RESTORE T1
>
JRST NXCOK ;EXIT-FOUND A GOOD IOWD
;ROUTIE TO MAKE THE USER AREA REPRESENTED
;BY THE IOWD IN T1 ADDRESSABLE.
;IF THIS IS A KA10, THE IOWD IS BAD (ADDRESS
;CHECK), OR THE IOWD IS THE LIST TERMINATOR,
;RETURN IMMEDIATELY. IF THIS IS AN I/O BUS
;DEVICE, MAPE THE NEW IOWD IN THE EXEC
;MAP. THIS CAN ONLY FAIL IF THE NUMBER
;OF PAGES THIS JOB HAS IN THE EXEC
;MAP IS NOT GREAT ENOUGH TO COVER
;THE IOWD (ONLY HAPPEMS IF I/O INTO THE
;LIST SINCE THE LIST IS SCANNED AT UUO
;LEVEL).
NXOUT: JUMPE T1,T2POPJ## ;LAST WORD IN THE LIST OR ADDRESS CHECK?
;YES, RESTORE T2 AND RETURN
IFN FTKI10!FTKL10,<
SKIPN DEVEVM(F) ; THE DEVICE GOES DIRECT TO MEMORY
; THROUGH A CHANNEL
JRST NXOUTA ; JUST RELOCATED THE IOWD KA10 STYLE AND RETURN
PUSH P,T3 ;SAVE LOWER BOUND ON I/O
HLRE T2,T1 ;T2 = - WORD COUNT FOR CURRENT IOWD
MOVNS T2 ;T2 = POSITIVE WORD COUNT
SUBI T2,2 ;CALCULATE NUMBER OF PAGES NECESSARY
IDIVI T2,PAGSIZ##+2 ; TO COVER THIS WORD COUNT BY MAPPING THE
ADDI T2,2 ; AREA SPECIFIED BY THE IOWD IN THE EXEC MAP
LDB T3,PDEVMS## ;GET THE NUMBER OF PAGES OF EVM ALLOCATED
; TO THIS DEVICE
MOVEI S,-1 ;ASSUME THERE ARE NOT ENOUGH
CAMLE T2,T3 ;ARE THERE ENOUGH PAGES TO COVER CURRENT
; WORD COUNT?
JRST NXOUT1 ;NO, ADDRESS CHECK RETURN
PUSH P,T1 ;SAVE THE IOWD
PUSHJ P,SAVDDL## ;ADJUST IOWD FOR HIGH SEGMENT SAVE
PUSHJ P,UVACKS## ;COMPUTE UVA IN CASE SSAVE IN PROGRESS
MOVEI T3,1(T2) ;ADDRESS INTO WHICH I/O WILL BE DONE
LDB T2,PDEVMS## ;RESTORE NUMBER OF PAGES
LDB T1,PDEVM## ;GET PAGE NUMBER OF FIRST PAGE IN THE EXEC
; MAP ALLOCATED TO THIS DEVICE
PUSHJ P,MAPUEI## ;MAP THE IOWD IN THE EXEC MAP
MOVEI S,0 ;FLAG CURRENT IOWD OK
HRRM T3,(P) ;STORE EXEC VIRTUAL ADDRESS IN IOWD
POP P,T1 ;T1 = XWD -N,EXEC VIRTUAL ADDRESS FOR I/O
NXOUT1: POP P,T3 ;RESTORE LOWER BOUND ON I/O TO USER AREA
SOJA T1,T2POPJ## ;RESTORE UPPER BOUND AND RETURN
>
NXOUTA: IFN FT2REL,<
CONSO PI,PIPROG## ;DON'T DIDDLE IOWD AT INTERRUPT LEVEL
PUSHJ P,SAVDDL## ;ADJUST IOWD FOR HIGH SEGMENT SAVE/GET
>
MOVE T2,T1 ;GUARD AGAINST CARRY INTO THE LEFT HALF WORD
ADDI T1,(R) ;RELOCATE
HLL T1,T2 ;RESTORE THE WORD COUNT
JRST T2POPJ## ;RESTORE T2 AND RETURN
SUBTTL DDB SCAN LOGIC
;ASSIGN DEVICE IF UNASSIGNED
;CALL: MOVE J, JOB NUMBER
; MOVE F, ADDR. OF DDB
; MOVE T1,DEVICE NAME
; MOVEI T2, EITHER ASSPRG OR ASSCON
; PUSHJ P, ASSASG
; CAN'T ASSIGN RETURN
; ASSIGNED RETURN
ASSASG::
IFN FTDISK,<IFN FTSPL,<
PUSHJ P,SAVE2##
SETZB P1,P2 ;P1 WILL GET DEVMOD IF SPOOLING
HRRZ T3,SPLBIT##(F) ;POSSIBLE SPOOL-BIT
SKIPN DEVCHR(F) ;FAKE (TABLE) DDB?
JRST ASSAS0 ;YES, SPOOL IT
LDB T3,DEYSPL## ;SPOOL BIT FOR THE DEVICE
SKIPGE DEVSPL(F) ;IS THIS A SPOOLED DISK DDB ?
TLOA T3,DEPSPL ;YES. ENSURE COPY HAS DEPSPL ON
TDNN T3,JBTSPL##(J) ;JOB SPOOLING THIS DEVICE?
JRST ASSAS1 ;NO
MOVE P2,T3 ;SPOOL BIT
LDB T3,PJOBN## ;YES, GET OWNER OF DEVICE
MOVE T4,DEVMOD(F) ;DEVMOD
TRNE T4,ASSCON ;ASSIGNED BY CONSOLE?
CAME T3,J ;YES. TO THIS JOB?
ASSAS0: TLOA T3,DEPSPL(P2) ;NO. SET UP TO SPOOL
JRST ASSAS2 ;YES - USE PHYSICAL DEVICE
MOVE P1,DEVMOD(F) ;TELL SETDDB TO STUFF THIS IN DEVMOD
HRRI F,DSKDDB## ;SET F TO PROTOTYPE DISK DDB
ASSAS1:> ;CLOSE FTSPL CONDITIONAL
MOVE T4,DEVMOD(F) ;DEVMOD
TLNN T4,DVDSK ;DEVICE A DISK?
JRST ASAS1A ;NO
PUSHJ P,SETDDB## ;YES, GENERATE A NEW DDB
JRST ASSAS5 ;NO DDB SPACE
ASAS1A:
IFN FTSPL,<
HLLZS T3 ;LH(T3)=0 OR DEPSPL
IORM T3,DEVSPL(F) ;LIGHT SPOOL-BIT IF NEEDED
ASSAS2:> ;CLOSE FTSPL
> ;CLOSE FTDISK
NOSCHEDULE ;DISABLE SCHEDULING
MOVEI T3,DEPMSG
TDNE T3,DEVMSG(F) ;CONTROLLED BY MPX?
JRST ASSAS5 ;YES, ALWAYS FAIL
LDB T1,PJOBN## ;GET JOB NUMBER IN DEV DATA BLOCK
CAMN T1,J ;IS IT ALREADY ASSIGNED TO THIS JOB
JRST ASSA2C ;YES
MOVEI T1,ASSPRG+ASSCON ;NO, IS IT ASSIGNED TO ANOTHER JOB?
IFN FTKL10,<
CONO PI,PIOFF## ;TEMPORARY UNTIL KL PI SYSTEM FIXED
CONO PI,SCNOFF##+PI.ON
> ;END IFN FTKL10
IFE FTKL10,<
CONO PI,SCNOFF## ;TURN SCANNER OFF
>
TDNE T1, DEVMOD(F) ;ARE EITHER ASSIGNED BITS SET?
JRST ASSAS4 ;YES
HRLZI T1,DEPRAS ;GET RESTRICTED ASSIGNMENT BIT
TDNN T1,DEVSTA(F) ;IS THIS DEVICE RESTRICTED?
JRST ASSA2A ;NO, PROCEED
PUSHJ P,PRVJ## ;THIS JOB PRIVILEDGED TO ASSIGN?
JRST ASSA2A
JRST ASSA4A ;NO, SET T2=-1 AS FLAG
ASSA2A:
IFN FTGALAXY,<
SKIPE %SIMDA## ;MDA NOT RUNNING?
CAMN J,MDAJOB## ;OR JOB=MDAJOB
JRST ASSA2B ;YES, SKIP ALL THIS
MOVSI T1,DVCMDA ;A CONTROLLED DEVICE?
TDNE T1,DEVCHR(F) ;?
JRST ASSA4A ;YES, LOSE
> ;END IFN FTGALAXY
ASSA2B: PUSH P,T2 ;SAVE T2 OVER CALL TO SETDVL
PUSHJ P,SETDVL ;STORE JOB NUMBER IN DDB
POP P,T2 ;RESTORE T2
IORM T2,DEVMOD(F) ;SET IN USE BITS
CONO PI,SCNON## ;TURN SCANNER ON
ASSA2C:
IFN FTMTSET,<
TRNN T2,ASSCON ;IF ASSIGN COMMAND,
JRST ASSAS3
HLLZ T1,DEVMOD(F) ;GET CHARACTERISTICS, SET RH FOR DPB
TLNE T1,DVMTA ;CHECK FOR MTA
TLNE T1,DVTTY ;BE SURE IT ISN'T NUL!
JRST ASSAS3 ;NOT MTA
HRRI T3,MTSIZ##+1 ;GET DEFAULT MTA BLOCK SIZE
DPB T3,PBUFSZ## ; SET SYSTEM DEFAULT BUFFER
DPB T1,TDYDN1## ; SET TO FORCE INSTALLATION DENSITY
DPB T1,PBUFRM## ;CLEAR FRAME-COUNT
IFN FTDX10,<
DPB T1,PMTRTY## ;ENABLE AUTO ERROR-RETRY
>
> ;END CONDITIONAL ON FTMTSET
ASSAS3: SCHEDULE ;TURN SCHEDULING ON
IFN FTGALAXY,<
MOVSI T1,DVCMDA ;CONTROLLED?
TDNE T1,DEVCHR(F) ;IS IT?
SKIPN %SIMDA## ;IF MDA ISN'T RUNNING
JRST ASSA3A ;NO HASLES
MOVSI T1,DVDATJ ;ALLOCATED?
TDNN T1,DEVCHR(F) ;?
JRST ASSA4A ;NO, LOSE
> ;END IFN FTGALAXY
ASSA3A: IORM T2,DEVMOD(F) ;SET IN USE BITS AGAIN IN CASE
; IT IS THE SAME JOB
JRST CPOPJ1## ;GIVE OK RETURN
;HERE IF CAN NOT DO IT
ASSA4A: HRREI T2,-1 ;FLAG AS RESTRICTED DEVICE
ASSAS4: CONO PI,SCNON## ;TURN SCANNER ON
SCHEDULE ;TURN SCHEDULING ON
ASSAS5: POPJ P, ;GIVE ERROR RETURN
IFN FT5UUO!FTNET!FTSFD,<
;DVCNSG -- ROUTINE TO FIND DDB FOR THOSE UUOS
; WHICH HAVE DUAL STYLE ARGUMENT:
; (1) 0-17 = CHANNEL NUMBER (INITED)
; (2) ELSE = SIXBIT DEVICE NAME (GENERIC,...)
;CALL: MOVE T1,ARGUMENT
; PUSHJ P,DVCNSG
;RETURN CPOPJ IF NO SUCH DEVICE
;SKIP RETURN WITH F = DDB ADDRESS IF FOUND
DVCNSG::CAILE T1,17 ;SKIP IF KNOWN NOT TO BE A UDX
PUSHJ P,UDXDDB ;SEE IF T1 IS A UDX
SKIPA ;NO--DO ORDINARY STUFF
JRST CPOPJ1## ;YES--ALL DONE
SKIPL T1 ;IF NEGATIVE
CAILE T1,17 ; OR .GT. 17,
PJRST DEVSRG ; MUST BE SIXBIT
SKIPE F,USRJDA##(T1) ;GET DDB IF SETUP
CAMLE T1,USRHCU## ;CHECK FOR LEGALITY
POPJ P, ;ERROR IF BAD
JRST CPOPJ1## ;WIN IF ALL OK.
> ;END CONDITIONAL ON FT5UUO!FTNET!FTSFD
;SUBROUTINES TO MAINTAIN THE LOGICAL NAME TABLE. THIS IS USED TO
; SPEED UP THE LOGICAL NAME SEARCHING.
LDVTLN==4 ;LENGTH OF THE TABLE IN WORDS.
INTERNAL FTHSLN
;SUBROUTINE TO MARK THE DDB IN F AS OWNED BY THE JOB IN J.
; IF THE DEVICE HAS A NON-BLANK LOGICAL NAME IT IS PUT IN
; THE JOB'S LOGICAL NAME TABLE.
SETDVL::PUSHJ P,CLRDVL ;CLEAR CURRENT OWNER, IF ANY.
DPB J,PJOBN## ;STORE JOB NUMBER IN DDB
IFN FTHSLN,<
JUMPE J,CPOPJ## ;ALL DONE IF JOB ZERO.
SKIPN DEVLOG(F) ;HAS THE DEVICE A LOG. NAME?
POPJ P, ;NO, ALL DONE.
PUSHJ P,FNDPDB## ;FIND JOB'S PDB
POPJ P, ;NONE, FORGET IT.
SKIPLE T1,.PDDVL##(W) ;IS THERE ALREADY A DDB TABLE?
PJRST SETDV1 ;YES, JUST ADD TO EXISTING SET
; PJRST SETDVS ;NO, BUILD ONE.
;SUBROUTINE TO BUILD THE LOGICAL NAME TABLE. USED WHEN THE FIRST
; LOGICAL NAME IS ASSIGNED AND IF THE NUMBER OF LOGICAL NAMES
; BECOMES TOO LARGE.
SETDVS: MOVEI T2,LDVTLN ;OBTAIN THE TABLE SPACE
JUMPE T2,SETDV2 ; THERE IS NONE, SCAN THE DDBS.
PUSHJ P,GETWDS## ;GET THAT MANY WORDS
JRST SETDV2 ; NOT AVAIL, SCAN DDBS FOR LOG NAMES.
HRLZ T2,T1 ;GOT THE SPACE -- CLEAR THE BLOCK.
HRRI T2,1(T1) ;FORM BLT ADDRESSES
SETZM (T1) ;CLEAR FIRST WORD
BLT T2,LDVTLN-1(T1) ;CLEAR THE REST OF THE WORDS
SKIPL .PDDVL(W) ;WERE THERE NO LOGICAL NAMES?
JRST SETDV3 ;YES, JUST STORE THIS DDB.
;COME HERE IF THERE WERE TOO MANY LOGICAL NAMES TO FIT IN THE
; TABLE. TRY TO REBUILD THE TABLE BY SCANNING THE DDBS.
MOVEM T1,.PDDVL##(W) ;STORE POINTER TO TABLE
PUSH P,F ;PRESERVE F
HLRZ F,DEVLST## ;SCAN ALL DDBS
SETDV4: SKIPN DEVLOG(F) ;HAS THIS DDB A LOGICAL NAME?
JRST SETDV8 ;NO, TRY NEXT DDB.
LDB T1,PJOBN## ;YES, BELONG TO THIS JOB?
CAMN T1,J
PUSHJ P,SETDV1 ;YES, PUT IN LOG NAME TABLE
SETDV8: HLRZ F,DEVSER(F) ;GET NEXT DDB
JUMPN F,SETDV4 ;DO THE REST OF THE LIST
POP P,F ;RESTORE F
POPJ P, ;AND RETURN.
;COME HERE IF CORE WAS GOTTEN SUCCESSFULLY AND THIS IS THE FIRST
; DEVICE WITH A LOGICAL NAME.
SETDV3: MOVEM T1,.PDDVL##(W) ;STORE POINTER TO TABLE
; PJRST SETDV1 ;PUT THIS DDB IN THE TABLE
;SUBROUTINE TO ADD A DDB POINTER TO THE SET OF POINTERS ALREADY
; ASSOCIATED WITH A JOB. IF THE TABLE IS FULL IT IS RELEASED
; AND LOGICAL NAME SEARCHING WILL BE DONE BY SCANNING ALL DDBS
; UNTIL THE NUMBER OF LOGICAL NAMES GETS SMALL ENOUGH TO FIT
; IN THE TABLE. DDB POINTER IN F, JOB NUMBER IN J.
SETDV1: SKIPG T1,.PDDVL##(W) ;IS THERE A TABLE?
POPJ P, ;NO, FORGET IT.
HRLI T1,-LDVTLN ;LENGTH OF TABLE (FOR AOBJN)
SETDV7: SKIPN T2,(T1) ;IS THE WORD ZERO?
JRST SETDV5 ;YES, USE LEFT HALF.
TLZN T2,-1 ;NO, IS L.H. ZERO?
JRST SETDV5 ;YES, USE IT.
JUMPE T2,SETDV6 ;NO, IF R.H. IS ZERO, USE IT.
AOBJN T1,SETDV7 ;BOTH NON-ZERO, TRY NEXT WORD.
; PJRST SETDVF ;TOO MANY, FLUSH TABLE.
;SUBROUTINE TO RETURN THE TABLE TO FREE STORAGE AND
; ARRANGE TO USE DDB SCAN. USED IF THERE ARE TOO MANY LOGICAL
; NAMES TO FIT IN THE TABLE.
SETDVF: MOVEI T1,LDVTLN ;LENGTH OF TABLE
MOVE T2,.PDDVL##(W) ;POINT TO TABLE
PUSHJ P,GIVWDS## ;RETURN THE TABLE SPACE
;COME HERE IF THE TABLE SPACE IS UNAVAILABLE OR, AFTER RETURNING
; TABLE, IF THERE ARE TOO MANY LOGICAL NAMES.
SETDV2: SETOM .PDDVL##(W) ;FLAG NO VALID TABLE
> ;END OF IFN FTHSLN
POPJ P, ;RETURN.
IFN FTHSLN,<
;COME HERE IF L.H. IS ZERO AND THEREFORE SUITABLE FOR A DDB POINTER
SETDV5: HRLM F,(T1) ;STORE DDB POINTER IN TABLE
POPJ P, ; AND RETURN.
;COME HERE FIR R.H.
SETDV6: HRRM F,(T1) ;STORE DDB POINTER IN TABLE
POPJ P, ; AND RETURN.
> ;END OF IFN FTHSLN
;SUBROUTINE TO TERMINATE OWNERSHIP OF A DEVICE. F POINTS TO THE
; DDB. PRESERVES J.
CLRDVL::LDB T1,PJOBN## ;FIND OWNER
JUMPE T1,CPOPJ## ;NONE, NO PROBLEM.
SETZ T2, ;CLEAR JOB NUMBER IN DDB
IFN FTNET,<
MOVSI T3,DVCNET ;ON NETWORK?
TDNN T3,DEVCHR(F) ;SKIP FOR ZAPNET
>;END IFN FTNET
DPB T2,PJOBN##
IFN FTHSLN,<
PUSH P,J ;PRESERVE J
MOVE J,T1 ;J = JOB NUMBER
PUSHJ P,FNDPDB## ;LOCATE JOB'S PDB
JRST JPOPJ## ;NONE, FORGET IT.
SKIPG T1,.PDDVL##(W) ;POINT TO LOGICAL NAME TABLE
JRST CLRDV1 ;NONE, TRY TO REBUILD.
HRRZ T3,F ;GET COPY OF F WITH L.H = 0
HRLI T1,-LDVTLN ;FIND THE DEVICE
CLRDV2: SKIPN T2,(T1) ;IS WHOLE WORD ZERO?
JRST CLRDV8 ;YES, TRY NEXT WORD.
CAIN T3,(T2) ;NO, DOES R.H. POINT TO DDB?
JRST CLRDV4 ;YES.
HLRZS T2 ;NO, TRY LEFT HALF
CAIN T3,(T2) ;DOES L.H. POINT TO DDB?
JRST CLRDV3 ;YES.
CLRDV8: AOBJN T1,CLRDV2 ;NO, TRY NEXT WORD.
POP P,J ;NOT IN TABLE. RESTORE J.
> ;END OF IFN FTHSLN
POPJ P, ;EXIT.
IFN FTHSLN,<
;COME HERE IF L.H. POINTER MATCHES. CLEAR IT.
CLRDV3: HRRZS (T1) ;LEAVE R.H. POINTER, IF ANY.
JRST CLRDV5 ; CHECK FOR EMPTY BLOCK
;COME HERE FOR R.H.
CLRDV4: HLLZS (T1) ;PRESERVE L.H. POINTER, IF ANY.
; JRST CLRDV5 ; AND CHECK FOR EMPTY BLOCK.
;COME HERE TO CHECK FOR AN EMPTY BLOCK. IF THE BLOCK IS
; EMPTY IT CAN BE FREED.
CLRDV5: SKIPG T1,.PDDVL##(W) ;POINT TO LOGICAL NAME TABLE
JRST JPOPJ## ;NONE, RESTORE J AND EXIT.
HRLI T1,-LDVTLN ;BUILD AOBJN POINTER
CLRDV6: SKIPN (T1) ;CHECK POINTERS TWO AT A TIME
AOBJN T1,CLRDV6 ;DONE THEM ALL?
JUMPL T1,JPOPJ## ;AT LEAST ONE POINTER.
PUSHJ P,SETDVF ;NO POINTERS, FLUSH TABLE.
SETZM .PDDVL##(W) ;MARK JOB AS HAVING NO LOG. NAMES
JRST JPOPJ## ;RESTORE J AND RETURN.
;COME HERE IF THE TABLE IS NOT PRESENT. TRY TO REBUILD IT.
CLRDV1: JUMPE T1,JPOPJ## ;IGNORE IF "NONE" RATHER THAN "INVALID"
PUSHJ P,SETDVS ;TRY TO REBUILD TABLE
JRST JPOPJ## ;RESTORE J AND RETURN.
> ;END OF IFN FTHSLN
;ROUTINE TO SEARCH FOR A DEVICE
;CALL: HRR J,JOB NUMBER
; MOVE T1,[SIXBIT .DEVICE NAME.]
; PUSHJ P, DEVSRC
; NOT FOUND
; FOUND
DEVSRC::
MOVEI T2,DD%PHY ;SET UP FOR PHYSICAL SEARCH
IFE FT5UUO,<
IFN FTLOGIN,<
MOVSI F,JLOG ;DO NOT ALLOW LOGICAL NAMES IF JOB IS NOT
;LOGGED IN OR ON BEING LOGGED OUT
TDNE F,JBTSTS##(J)
>>
TRO T2,DD%LOG ;SEARCH FOR LOGICAL TOO
PJRST DDBSRC ;GO DO IT
;SEARCH LOGICAL NAMES
DEVLG::
MOVEI T2,DD%LOG ;SEARCH FOR LOGICAL NAMES
PJRST DDBSRC ;GO DO IT
;come here to search for physical name
devphy::
movei t2,dd%phy ;set physical only flag
pjrst ddbsrc ; and go do the search
IFN FT5UUO!FTNET!FTSFD,<
;ROUTINE TO SEARCH FOR A DEVICE
; (INCLUDING GENERIC NAMES)
;SAME CALL AND RETURN AS DEVSRC
DEVSRG::PUSHJ P,DEVSRC ;SEARCH PHYSICAL & LOGICAL NAMES
TDZA T3,T3 ;NOT FOUND
JRST CPOPJ1## ;FOUND
IFN FTSPL,<
;CALL DVSRSP TO SEARCH THE SPOOLING TABLE
; AND IF FAILS, GENERIC SEARCH
DVSRSP::HLLZ T2,T1 ;GENERIC NAME OF DEVICE
MOVEI F,SPLTAB## ;SCAN SPOOLABLE DEVICE TABLE FOR MATCH
SPLOOP: CAMN T2,SPLNAM##(F)
JRST SPLFND ;FOUND
ADDI F,SPLLEN##
CAIGE F,SPLTOP##
JRST SPLOOP
JRST SPLEND ;NOT A SPOOLING DEVICE - SCAN FOR GENERIC MATCH
SPLFND: HRRZ T2,SPLBIT##(F) ;SPOOLING DEVICE BIT
TDNN T2,JBTSPL##(J) ;JOB SPOOLING THIS DEVICE?
JRST SPLEND ;NO, FIND THE REAL DDB
HRRZ T2,T1
JUMPE T2,CPOPJ1## ;WE WON IF NO RH OF NAME
IFN FTNET,<
LSH T2,-6
PUSHJ P,DVSCVT
JRST SPLEND ;NO - NOT REALLY SPOOLING
PUSH P,T1
MOVE T1,T2 ;RH = SXX. IS XX A STATION?
PUSHJ P,STBSCA## ;DOES THE NODE EXIST
TDZA T3,T3 ;NO, SET T3 FOR DVASRC
JRST TPOPJ1## ;YES, GIVE SKIP RETURN
POP P,T1 ;RESTORE NAME
>;END FTNET CONDITIONAL
SPLEND: SETZ F, ;CLEAR F (NO DDB)
>;END FTSPL CONDITIONAL
IFN FTGSRC,<
PJRST DVASRC ;SEARCH FOR GENERIC, GIVE ERROR OR OK RETURN
>
IFE FTGSRC,<
SETZ T4, ;RESET FLAG
POPJ P, ;ERROR RETURN
>
> ;END CONDITIONAL ON FT5UUO!FTSFD
IFE FT5UUO!FTNET!FTSFD,<
DEVSRG==:DEVSRC
>
;ROUTINE TO CHECK TO SEE IF DEVICE 'OPRXXX' AND IF SO TO
;FUDGE T1 TO HAVE REAL TTY NAME IN IT
TSTOPR::
IFN FTNET,<
PUSH P,T1 ;SAVE NAME IN CASE TEST FAILS
HLRZ T2,T1 ;GET GENERIC NAME
CAIE T2,(SIXBIT/OPR/) ;IS IT OPR?
JRST TPOPJ## ;NO - BRANCH TO RESTORE OLD NAME
TRNN T1,-1 ;ANY STATION NUMBER SPECIFIED?
JRST OPRGEN ;NO - GO FIND OPR FOR THIS JOB
HRLZS T1 ;PUT NUMBER IN LH OF T1
PUSHJ P,CVTOCT ;GO CONVERT TO OCTAL DIGITS
JRST TPOPJ## ;ILLEGAL OCTAL - MUST NOT BE OPR
JUMPE T1,OPRCEN ;OPR0 IS ALWAYS CENTRAL SITE
PUSHJ P,STBSCA## ;GO SEE IF STA # IS VALID
JRST TPOPJ## ;INVALID STA - ERROR RETURN
OPRFND: CAMN T1,JBTLOC## ;IS IT AT CENTRAL SITE?
JRST OPRCEN ;YES--GO GET IT
PUSHJ P,STBOPR## ;GET OPR TTY LINE # AT THIS STA
PUSHJ P,CVTSBT ;CONVERT IT TO SIXBIT
HLRZS T1 ;PUT IN RH
HRLI T1,(SIXBIT/TTY/) ;LH = SIXBIT/TTY/
OPRRET: PJRST T2POPJ## ;THROW AWAY OLD NAME (T2) AND RETURN
OPRGEN: MOVE T1,JBTLOC##(J) ;GET STA # OF JOB
JRST OPRFND ;NO - USE JOB LOCATION FOR OPR SEARCH
OPRCEN: MOVE T1,DEVOPR## ;YES - USE OPR NAME FROM COMMON
JRST OPRRET ;SCRAP OLD NAME AND RETURN
> ;END CONDITIONAL ON FTNET
IFE FTNET,<
CAMN T1,[SIXBIT/OPR/] ;IS IT DEVICE OPR?
MOVE T1,DEVOPR## ;YES - USE OPR DEV NAME
POPJ P, ;AND RETURN
>
IFN FTNET!FTMSGSER,<
;NUMBER CONVERSION ROUTINES
;CVTOCT - CONVERT SIXBIT NUMBER LEFT JUSTIFIED IN T1 TO
;OCTAL (RIGHT JUSTIFIED) IN T1
CVTOCT::TLNN T1,770000 ;IS THERE A FIRST CHARACTER?
JUMPN T1,CPOPJ## ;NO, CAN'T BE SIXBIT
PUSH P,T2 ;SAVE ALL AC'S USED
PUSH P,T3 ;..
PUSH P,T4 ;..
MOVE T2,[POINT 6,T1] ;BYTE PTR TO T1
SETZ T3,
CVTOC2: ILDB T4,T2 ;GET SIXBIT CHAR
JUMPE T4,CVTOC1 ;NULL CHAR ENDS STRING
CAIL T4,'0' ;MUST BE BETWEEN 0 AND 7
CAILE T4,'7' ;TO BE A VALID OCTAL DIGIT
JRST CVTOC3 ;OTHERWISE ERROR RETURN
ROT T3,3 ;MAKE ROOM
IORI T3,-'0'(T4) ;PUT DIGIT IN
JRST CVTOC2 ;GO DO SOME MORE
CVTOC1: MOVE T1,T3 ;RETURN WITH OCTAL NUMBER IN T1
AOS -3(P) ;GOOD RETURN IS SKIP RETURN
PJRST CVTOC3 ;GO RESTORE AC'S AND RETURN
> ;END CONDITIONAL ON FTNET!FTMSG
;CVTSBT - CONVERT OCTAL NUMBER TO SIXBIT
CVTSBT::PUSH P,T2 ;SAVE ALL AC'S USED
PUSH P,T3 ;..
PUSH P,T4 ;..
MOVE T3,[POINT 6,T4] ;PLACE FOR RESULT
SETZ T4, ;ZERO T4
PUSHJ P,CVTSB1 ;CONVERT TO SIXBIT
MOVE T1,T4 ;RETURN RESULT IN T1
CVTOC3: POP P,T4 ;RESTORE AC'S
POP P,T3
PJRST T2POPJ## ;AND RETURN (POP T2)
CVTSB1: IDIVI T1,10 ;GET A DIGIT
HRLM T2,0(P) ;SAVE IN LH OF CURRENT STACK WORD
SKIPE T1 ;WHEN DONE - SKIP
PUSHJ P,CVTSB1 ;RECURSIVELY DO ABOVE AGAIN
HLRZ T1,0(P) ;GET BACK THE DIGIT
ADDI T1,20 ;CONVERT IT TO SIXBIT
IDPB T1,T3 ;STORE IN RETURN WORD
POPJ P,0 ;AND RETURN TO GET ANOTHER DIGIT
;OR CALLER
;SUBROUTINE TO CHECK FOR A VALID (PDP-11 COMPATABLE) 2-CHAR
; DEVICE NAME. ENTER WITH NAME IN T1, EXIT WITH NEW NAME (IF ANY)
; ALSO IN T1.
;
;CALL:
; PUSHJ P,CK2CHR
; HERE ALWAYS
;
;
CK2CHR: MOVEI T4,STLEN## ;GET POINTER TO SPECIAL DEVICE TABLE
HLRZ T2,T1 ;GET THIS DEVICE NAME
DVSRC1:
MOVE T3,SPCTAB##(T4) ;GET TABLE ENTRY
CAIN T2,(T3) ;IS IT THIS DEVICE?
JRST [HLL T1,T3 ;YES, RESET DEVICE NAME
POPJ P,] ;AND RETURN
SOJGE T4,DVSRC1 ;MORE IN TABLE?
POPJ P, ;NO, EXIT
;SUBROUTINE TO SEARCH DDB'S FOR A DEVICE
;
;CALL:
; MOVEI T2,FLAGS
; PUSHJ P,DDBSRC
; NOT FOUND
; FOUND
;
;FLAGS:
; DD%PHY SEARCH FOR PHYSICAL NAMES
; DD%LOG SEARCH FOR LOGICAL NAMES
;
;ON EXIT, F WILL CONTAIN THE DDB IF WE FOUND ONE
;RETURNS T2=PREDECESSOR ON PHYSICAL MATCH OF DEVNAM
;
;THE ALGORITHM IS AS FOLLOWS:
;
; 1. IF LOGNAM MATCH & DD%LOG SET, TAKE THIS DEVICE
; 2. OR, IF PHYNAM MATCH & DD%PHY SET & DD%LOG NOT SET, TAKE IT
; 3. IF PHYNAM MATCH & BOTH SET, SAVE NAME TO SEE IF FIND LOGNAM MATCH
;
DD%LOG==:1B35 ;FLAG BIT DEFINITIONS
DD%PHY==:1B34
DDBSRC: JUMPE T1,CPOPJ## ;DEVICE NAME OF 0 NOT ALLOWED
PUSHJ P,SAVE1## ;SAVE P1
HRR P1,T2 ;SAVE FLAGS
IFN FTHSLN,<
TRNN P1,DD%LOG ;LOGICAL SEARCH?
>
JRST NOLGST ;NO, DON'T SET UP
IFN FTPHYO,<
HLRZ T2,P1 ;CHECK FOR PHYSICAL ONLY
CAIN T2,PHONLY ;IS IT THERE?
JRST DEVLP7 ;YES, CLEAR LOGICAL BIT
> ;END OF FTPHYO
IFN FTHSLN,<
PUSHJ P,FNDPDB## ;POINT TO PDB
JRST DEVLP7 ;NO PDB = NO LOGICAL NAMES
SKIPGE T2,.PDDVL##(W) ;IS THERE A LOG NAME TABLE?
JRST NOLGST ;IT IS INVALID, SCAN DDB'S
JUMPE T2,DEVLP7 ;NO LOGICAL NAMES
HRLI T2,-LDVTLN ;SET UP AOBJN POINTER
DEVLP4: SKIPN T3,(T2) ;IS THIS WORD CLEAR?
JRST DEVLP5 ;YES, CHECK NEXT
HLRZ F,T3 ;NO, CHECK LEFT HALF
CAMN T1,DEVLOG(F) ;LOGICAL NAME MATCH?
JUMPN F,CPOPJ1## ;YES, IF NON-BLANK
HRRZ F,T3 ;TRY RIGHT HALF
CAMN T1,DEVLOG(F) ;LOGICAL NAME MATCH?
JUMPN F,CPOPJ1## ;YES, IF NON-BLANK
DEVLP5: AOBJN T2,DEVLP4 ;CHECK ON NEXT WORD
> ;END OF IFN FTHSLN
DEVLP7: TRNN P1,DD%PHY ;PHYSICAL?
POPJ P, ;NO, NOT FOUND
TRZ P1,DD%LOG ;YES, TURN OFF LOG
NOLGST: TLZ P1,-1 ;CLEAR PHONLY
TRNN P1,DD%PHY ;PHYSICAL SEARCH?
JRST DDSRC2 ;NO DON'T SET UP
TLNN T1,77 ;IS THIS A 2-CHAR DEVICE NAME?
PUSHJ P,CK2CHR ;YES, CHECK FOR WIERD NAMES
DDSRC0:
IFN FTDISK,<
PUSHJ P,TSTDSK## ;IS THIS A DISK?
JRST [TRNN P1,DD%LOG ;LOGICAL SEARCH?
JRST CPOPJ1## ;NO FOUND PHYSICAL
HRL P1,F ;YES, SAVE DDB
JRST .+1] ;AND CONTINUE
>
IFN FTTSK,<
PUSHJ P,TSTTSK## ;IS THIS A TSK DEVICE
CAIA ;NO, CONTINUE SEARCH
JRST CPOPJ1## ;YES, EXIT WITH F=DDB POINTER
>;END FTTSK
PUSHJ P,TSTOPR ;CHECK FOR "OPR"
IFE FTDISK,<
CAMN T1,[SIXBIT /SYS/] ;IS IT "SYS"?
SKIPA T1,SYSTAP## ;YES, CHANGE TO SYS TAPE DEVICE NAME
TDZA T2,T2 ;NO, CLEAR SYSTEM TAPE FLAG
MOVEI T2,SYSDEV ;YES, SET SYSTEM TAPE FLAG
>
MOVSI T3,DVDSK
DDSRC2: HLR F,DEVLST## ;GET START OF CHAIN
DDSC2A: TRNE P1,DD%LOG ;LOGICAL NAME SEARCH?
CAME T1,DEVLOG(F) ;LOGICAL NAME MATCH?
JRST GETPHY ;NO
LDB T4,PJOBN## ;CHECK JOB #
CAMN T4,J ;THIS JOB?
JRST [TLZ F,-1 ;CLEAR SYS BITS
JRST CPOPJ1##] ;GOOD RETURN
GETPHY:
TRNN P1,DD%PHY ;PHYSICAL SEARCH?
JRST DDSRC3 ;NO, SKIP OVER THIS
IFE FTDISK,<
TLO F,(T2) ;SET SYS TAPE FLAG IF SEARCHING FOR SYS
>
IFN FTSPL,<
SKIPGE DEVSPL(F) ;NO MATCH ON SPOOLED DDB'S
JRST DDSRC3 ;IT IS A SPOOLED DDB
>
TDNN T3,DEVMOD(F) ;IF TSTDSK SAYS IF ISN'T A DISK,
CAME T1,DEVNAM(F) ;OR IF DEVICE NAMES DON'T MATCH...
JRST DDSRC3 ;THEN IGNORE THIS ONE (SINGLE-ACCESS)
TLNN P1,-1 ;FOUND DDB ALREADY?
HRL P1,F ;SAVE THIS ADDRESS
TRNN P1,DD%LOG ;DO WE CARE ABOUT LOGICAL NAMES?
JRST CPOPJ1## ;NO, WE FOUND A PHYSICAL NAME
DDSRC3: HRRZ T2,F ;SAVE PREDECESSOR
HLR F,DEVSER(F) ;GET NEXT DDB
TRNE F,-1 ;END OF CHAIN?
JRST DDSC2A ;NO
TRNN P1,DD%PHY ;ARE WE LOOKING FOR PHYSICAL?
POPJ P, ;NO, AND WE DIDN'T FIND A LOGICAL MATCH
HLR F,P1 ;YES, GET SAVED ADDRESS
JUMPN F,CPOPJ1## ;EXIT WITH PHYSICAL DDB MATCH IF THERE WAS ONE
IFN FTRDX,<
PUSHJ P,TSTRDX## ;CHECK FOR REMOTE DATA ENTRY ROUTINE
SKIPA ;NO
JRST CPOPJ1## ;YES,
>;END IFN FTRDX
IFN FTNET,<
TRNN T1,505050 ;MUST ME NUMBERIC RT HALF
PUSHJ P,TSTNET## ;YES CHECK FOR NETWORK DEVICE
SKIPA ;NOT A NETWORK DEVICE
PJRST CPOPJ1## ;YES, FOUND THE DEVICE ON THE NETWORK
>;END FTNET
IFN FTMSGSER,<
PUSHJ P,TSTMPX## ;NO, CHECK FOR MPX DDB
SKIPA ;NO--TRY FOR TTY
JRST CPOPJ1## ;YES--ALL DONE
>;END FTMSGSER
CAME T1,[SIXBIT /TTY/] ;IS THIS PUBLIC LOGICAL NAME TTY?
JRST GETDDB## ;SEE IF IT'S A TTY
PUSH P,U ;SAVE OUTPUT BYTE PTR(TTY) OR INIT ARG ADR
PUSHJ P,TTYFND## ;FIND TTY JOB IS ATTACHED TO
JRST UPOPJ1## ;GOOD RETURN
IFN FTGSRC!FTSFD,<
;DVASRC - MODIFIED DDB SEARCH ROUTINE TO SEARCH FOR GENERIC
;DEVICE NAMES
;THIS ROUTINE SEGREGATES SPECIFICATIONS INTO THREE CLASSES:
; (1) SPECIFIC DEVICE - RH OF NAME IS NUMERIC
; - ERROR RETURN TAKEN - NOT GENERIC
; (2) GLOBAL GENERIC - RH OF NAME IS NULL
; - GENERIC SEARCH DONE FIRST AT JOB SITE
; IF NO SUCH DEVICE THERE SEARCH REPEATED AT
; CENTRAL SITE - OTHERWISE FAIL
; (3) SPEFICIED GENERIC - RH OF NAME IS NN WHERE NN
; IS THE STATION TO SEARCH AT
;INTERFACE TO DVSTAS PRESERVED (T3,T4)
DVASRC::SETZ T4, ;RESET INTERNAL FLAG
HRRZ T2,T1 ;GET RH OF NAME
TRNE T2,7777 ;CHECK FOR LOCAL GENERIC DEVICE GGU
JRST DVSSRC ;NI, SPECIFIC MODE GENERIC GGGNN
;USER HAS SPECIFIED GENERIC DEVICE WITH NO STATION SPECIFICATION
IFN FTNET,<
MOVE T2,JBTLOC##(J) ;GET THIS GUY'S STAION NUMBER
PUSHJ P,DVSTAS ;SEARCH FOR A DEVICE AT THIS STATION
SKIPA T2,JBTLOC## ;FAILED - TRY CENTRAL SITE (MAYBE)
JRST CPOPJ1## ;SUCCESS - FOUND A FREE DEVICE
JUMPL T4,CPOPJ## ;FAILED BUT FOUND AT LEAST ONE DEVICE
;THAT MET THE SPEC AND WAS BUSY (T4=-1 AND NONSKIP RETURN)
;NO DEVICE OF REQUIRED TYPE AT USER'S
;SITE SO TRY CENTRAL SITE
>
JRST DVSTAS ;GO DO GENERIC SEARCH
;STILL IN FTGSRC!FTNET!FTSFD CONDITIONAL
;ROUTINE TO CONVERT STATION NAME
;ENTER NAME IN T1
;EXIT CPOPJ IF STATION ILLEGAL
;EXIT CPOPJ1 IF OK, T2=STATION NUMBER
DVSCVT::PUSH P,T1 ;SAVE NAME
IFN FTNET,<
HRLZS T1 ;GET SNN
TLZ T1,77 ;NOW ONLY NN
PUSHJ P,CVTOCT ;GO CONVERT NN TO OCTAL NUMBER
JRST TPOPJ## ;ERROR IN NN SPEC
;MUST NOT HAVE BEEN SNN AFTER ALL
;SO RESTORE T1 AND GIVE ERROR RETURN
SKIPN T2,T1 ;IF NN IS ZERO PUT STA # IN T2
MOVE T2,JBTLOC## ;USE CENTRAL SITE NMBER
JRST TPOPJ1## ;GOOD RETURN.
>
IFE FTNET,<
HRRZS T1 ;IF NO REMOTES, ONLY STATION ZERO LEGAL
TRZ T1,77 ;CLEAR UNIT #
CAIN T1,'00 ' ;SKIP IF STATION 0
TDZA T2,T2 ;OK, SET T2=0 FOR CENTRAL SITE
JRST TPOPJ## ;NO, ILLEGAL
JRST TPOPJ1## ;RESTORE NAME AND GOOD RETURN
>
;USER HAS SPECIFIED NNU IN RH OF NAME
DVSSRC: PUSH P,T1
PUSHJ P,DVSCVT ;CONVERT NN TO OCTAL
JRST TPOPJ## ;ILLEGAL STATION NUMBER
DPB T1,[POINT 6,T1,23] ;LEFT JUSTIFY THE UNIT NUMBER IF ANY
TRZ T1,7777 ;CLEAR THE JUNK
;AND FALL INTO GENERIC SEARCH
;WITH NN AS STATION NUMBER
PUSHJ P,DVSTAS ;FIND DEVICE
JRST TPOPJ##
JRST TPOPJ1##
;STILL IN FTGSRC!FTNET!FTSFD CONDITIONAL
;ROUTINE TO FIND A GENERIC DEVICE AT A SPECIFIC STATION
;CALL:
; LH(T1) 3 CHAR GENERIC NAME TO SEARCH ON
; RT(T1) UNIT NUMBER OR 0
; C(T2) STATION TO SEARCH AT
; RH(T3) HAS BITS TO TEST FOR FAIL ANYWAY
;THIS ROUTINE GIVES SUCCESS RETURN (SKIP) ONLY IF
; (1) A FREE DEVICE IS FOUND WITH LH OF NAME MATCHING, OR
; (2) CURRENT JOB (IN J) HAS DEVICE FOR WHICH A LH
; MATCH HAS BEEN DONE AND THE DEVMOD BITS INDICATED IN T3 ARE OFF.
;THE DDB RETURNED WILL BE ONE ALREADY ASSIGNED TO THE JOB IF
;IT MEETS THE ABOVE CRITERIA
;C(T4) ARE RETURNED AS -1 IF A DEVICE MATCH IS MADE WHETHER OR NOT
;THE DEVICE CAN BE GIVEN TO THE JOB
;C(T4) .GE. 0 IF NO SUCH DEVICE
DVSTAS: JUMPE T1,CPOPJ##
PUSHJ P,SAVE3## ;SAVE P1-3
PUSH P,T1 ;SAVE T1
MOVEI T4,0 ;CLEAR FLAG
IFN FTNET,<
SKIPN T2 ;IF ZERO STA # USE CENTRAL SITE
MOVE T2,JBTLOC## ;FOR SEARCH
>
PUSHJ P,CHKGEN ;SEARCH FOR SPECIAL GENERIC DEVICE
JRST [SETZ F,
JRST TPOPJ##] ;DIDN'T FIND IT--BAD DEVICE NAME
SETZB P2,P3 ;INITIALLY NO FREE DDB
;STILL IN FTGSRC!FTNET!FTSFD CONDITIONAL
DVSTAL:
IFN FTNET,<
LDB P1,PDVTYP## ;DEVICE TYPE
CAIN P1,.TYPTY/.TYEST;A PTY?
JRST DVST1 ;YES, PTYS ARE AT THE CENTRAL SITE
LDB P1,PDVSTA## ;GET STA # FROM DDB
CAME P1,T2 ;IS IT THE RIGHT STA?
JUMPN T2,DVSNXT ;NO - TRY NEXT DDB IF NOT 0 (REMSW=0)
DVST1:>
HLLZ P1,DEVNAM(F) ;MATCH ON LH OF NAME (GENERIC)
TLNE T1,77 ;IS THIS A 2-CHAR NAME?
JRST DVST2
PUSHJ P,CKSPEC ;YES, CHECK FOR SPECIAL NAMES
JRST DVST2A
JRST DVST2 ;NONE FOUND, CONTINUE
PUSH P,T3 ;SAVE THIS
CAMN P1,[SIXBIT/LPT/] ;LL/LU
JRST DVLPTS ;IT'S A FUNNY LPT
HLRZ T3,TDVUDB##(F) ;IT'S A MAGTAPE, GET UDB
HRRZ T3,TUBCNF##(T3) ;GET CONFIG INFO
TRNN T3,TUC7TK## ;IS THIS 7-TRACK ?
SKIPA T3,[SIXBIT/M9/] ;NO, SETUP 9-TRACK
MOVSI T3,'M7 ' ;YES, SET UP NAME
JRST DVST0 ;GO COMPARE NAMES
DVLPTS: MOVSI P1,dvlptl ;SET UP BIT TO CHECK FOR LOWER CASE
TDNn P1,DEVchr(F) ;IS THIS A LC LPT?
SKIPA T3,[SIXBIT /LU/]
MOVSI T3,'LL '
DVST0: CAMN T1,T3 ;IS THIS WHAT WE WANT ?
JRST [POP P,T3
JRST DVST3] ;YES
POP P,T3 ;NO, FALL THRU NAME CHECK TO DVSNXT
DVST2: HRRZ P1,DEVNAM(F) ;GET THE UNIT NUMBER
LSH P1,14 ;POSITION TO HIGH ORDER
TRNN T1,770000 ;IS THERE S PHYSICAL UNIT FOR GENERIC
TRZ P1,770000 ;NO, CLEAR THE UNIT NUMBER
HLL P1,DEVNAM(F) ;MATCH ON LH OF NAME (GENERIC)
DVST2A: CAME P1,T1 ;
JRST DVSNXT ;N0 - TRY NEXT DDB
DVST3: MOVE P3,F ;SAVE ANYTHING HERE
HRROI T4,-1 ;SET FLAG (T4) TO -1 TO
;INDICATE THAT A DDB HAS BEEN FOUND
LDB P1,PJOBN## ;GET JOB DDB ASSIGNED TO
JUMPN P1,DVSNF ;BRANCH IF ASSIGNED TO SOMEBODY
MOVE P1,DEVMOD(F) ;GET ASSIGN BITS
TRNE P1,ASSCON+ASSPRG ;IS IT ASSIGNED TO JOB 0 ?
JRST DVSNXT ;YES - TRY NEXT DDB ANYWAY
IFE FTDISK,<
MOVE P1,DEVNAM(F) ;NO, PHYSICAL DEVICE NAME
CAMN P1,SYSTAP## ;IS IT THE SYSTEM TAPE?
JRST DVSNXT ;YES, KEEP LOOKING
>
MOVSI P1,DEPRAS ;GET RESTRICTED ASSIGNMENT BIT
TDNN P1,DEVSTA(F) ;IS THIS DEVICE RESTRICTED?
JRST DVSTA1 ;NO, PROCEED
MOVE P1,JBTPPN##(J) ;YES. GET JOB'S PRJ-PRG #
CAMN P1,FSFPPN## ;=1,2?
JRST DVSTA1 ;OK TO USE DEVICE
JUMPL M,DVSNXT ;CANNOT USE IF FROM COMMAND AND NOT 1,2
MOVSI P1,JACCT ;NOT [1,2]. CHECK PRIVILEGES
TDNN P1,JBTSTS##(J) ;JACCT ON?
JRST DVSNXT ;NO, LOOK AT OTHER DEVICES
DVSTA1: SKIPN P2 ;FOUND ONE BEFORE DON'T BOTHER
MOVE P2,F ;FOUND A FREE DEVICE THAT WE CAN USE-
;SAVE IT AND CONTINUE TO SEE IF WE
;CAN FIND ONE ALREADY ASSIGNED
;TO THIS JOB
JRST DVSNXT ;GO DO SOME MORE LOOKING
;STILL IN FTGSRC!FTNET!FTSFD CONDITIONAL
;HERE IF THIS DDB IS ALREADY ASSIGNED OR INITED TO SOME JOB
DVSNF: CAME P1,J ;DDB ASSIGNED TO THIS JOB ?
JRST DVSNXT ;NO - NICE TRY ANYWAY
TDNE T3,DEVMOD(F) ;YES -- IS HE USING THE DEVICE
;(IS THE DEVCE INIT'ED ON INIT OR
;ASSIGN'ED ON ASSIGN)?
JRST DVSNXT ;YES - CAN'T USE THIS ONE TRY NEXT
;FOUND A DEVICE ACCEPTABLE TO CALLER - OUR
;IDEAL CASE ! - GIVE GOOD RETURN WITH
JRST TPOPJ1## ;F SET UP
DVSNXT: HLRZ F,DEVSER(F) ;GET NEXT DDB ON CHAIN
JUMPE F,DVSNX2 ;END OF CHAIN
JRST DVSTAL ;NO, STILL LOOKING AT SAME DEVICES
DVSNX2:
JUMPE P2,DVSFL ;IF WE GET HERE AND
;P2 = 0 THEN WE HAVE FOUND NO DDB'S
;THAT ARE AVAILABLE (WE MAY HAVE
;FOUND DDB'S IN USE THO) - SO GIVE
;ERROR RETURN
MOVE F,P2 ;IF P2 IS NOT 0 HOWEVER, WE WERE
;TRYING TO FIND AN ASSIGNED DEVICE
;AND FAILED BUT DID PREVIOUSLY FIND
;A FREE DEVICE - SO USE IT
JRST TPOPJ1## ;GIVE GOOD RETURN WITH DDB IN F
DVSFL: JUMPN T3,DVSNET ;IF T3 WAS NOT ZERO - WE FAIL HERE
JUMPE P3,DVSNET ;IF T3=0, BUT NO SUCH DEVICE, FAIL
MOVE F,P3 ;HOWEVER, IF T3=0 AND THERE WAS
JRST TPOPJ1## ;SOME DEVICE (EVEN THO NOT
;AVAILABLE) GIVE IT TO CALLER
DVSNET: PUSHJ P,GENNET## ;TRY GENERIC NETWORK
PJRST TPOPJ## ;FAIL
PJRST TPOPJ1## ;WE WIN F=DDB
> ;END CONDITIONAL ON FTGSRC!FTNET!FTSFD
;SUBROUTINE TO CHECK FOR DEVICE NAME OF <LL,LU>
;
;CALL:
; HLLZ P1,DEVNAM(F)
; PUSHJ P,CKSPEC
; RETURN HERE IF MT OR DT
; RETURN HERE IF NOT LL OR LU
; HERE IF LL/LU <AND> P1 WAS SIXBIT /LPT/
; <OR> IF M7/M9 <AND> P1 WAS MTA/MTB/MTC
;
CKSPEC: CAME T1,[SIXBIT /LU/]
CAMN T1,[SIXBIT /LL/] ;IS IT ONE OF THOSE?
JRST CKSPC3 ;YES, GO CHECK FOR LPT
CAME T1,[SIXBIT /M7/] ;M7?
CAMN T1,[SIXBIT /M9/] ;M9?
JRST CKSPC4 ;YES
CAME T1,[SIXBIT /DT/] ;IS IT A "DT"?
CAMN T1,[SIXBIT /MT/] ;OR A "MT"?
TLZ P1,77 ;IF SO, FIX P1 SO A MATCH WILL BE SEEN
POPJ P, ;RETURN
CKSPC3: CAME P1,[SIXBIT /LPT/] ;IS THIS A LPT DDB?
JRST CPOPJ1## ;NO
JRST CPOPJ2## ;YES, WE WILL DO SPECIAL STUFF
CKSPC4: TLZ P1,77 ;CLEAR CONTROLLER TAPE
CAME P1,[SIXBIT/MT/] ;MT?
JRST CPOPJ1## ;NO
JRST CPOPJ2## ;YES
;SUBROUTINE TO SEARCH THE GENERIC DEVICE TABLE
;
;CALL:
; MOVE T1,[SIXBIT .DEVICE NAME.]
; PUSHJ P,CHKGEN
; HERE IF NOT FOUND
; HERE IF FOUND WITH F = DDB
;
;p2 is saved (for assign in comcon), p1 and p3 are destroyed
CHKGEN::
PUSH P,P2 ;SAVE P2
PUSH P,T1 ;SAVE OLD NAME
PUSHJ P,FXSNAM ;FIX-UP NAME
HLLZ P1,T1 ;GET DEVICE NAME
POP P,T1 ;RESTORE OLD NAME
MOVEI P2,GTLEN##-1 ;SET UP POINTER FOR GENERIC TABLE SEARCH
DVS2: HLLZ P3,GENTAB##(P2) ;GET DEVICE NAME FROM TABLE
CAMN P1,P3 ;MATCH?
JRST DVS3 ;YES, FOUND DEVICE
SOJGE P2,DVS2
JRST DVS5 ;NO, NONE ARE DEFINED
DVS3: HRRZ F,GENTAB##(P2) ;GET DDB POINTER
AOS -1(P) ;BUMP RETURN ADDRESS
SKIPN F ;SKIP RETURN IF DDB ADDRESS IN TABLE
DVS5: HLRZ F,DEVLST## ;NOT IN THE TABLE RETURN DEVLST
POP P,P2 ;GET P2 BACK
POPJ P, ;RETURN (CPOPJ OR CPOPJ1)
;SUBROUTINE TO FIX SPECIAL 2-CHAR DEVICE NAMES
;CALL:
; MOVE T1,[SIXBIT .DEVICE NAME.]
; PUSHJ P,FXSNAM
; HERE WITH T1 FIXED UP
FXSNAM::CAME T1,[SIXBIT /LU/] ;FUNNY LPT?
CAMN T1,[SIXBIT /LL/] ;...
HRLI T1,'LPT' ;YES
CAME T1,[SIXBIT /DT/] ;DT?
CAMN T1,[SIXBIT /MT/] ;MT?
TLO T1,' A' ;YES, ADD"A"
CAME T1,[SIXBIT /M7/] ;M7?
CAMN T1,[SIXBIT /M9/] ;OR M9?
HRLI T1,'MTA' ;YES
POPJ P, ;RETURN
SUBTTL BUFFER RING BUILDER & CLEARER
;ROUTINE TO SETUP N-RING IO BUFFER IN USER AREA
;CALL: MOVEI T2,ADDRESS OF BUFFER HEADER
; PUSHJ P,BUFCLC
; EXIT RETURNS HERE IF MEMORY NOT EXCEEDED
; SETS UP AN N BUFFER RING FOLLOWING THE USER'S PROGRAM, WHERE N
; IS IN THE ADDRESS FIELD OF AC M.
; THE BUFFER RING FORMAT IS AS FOLLOWS:
; LOCATION LH CONTENTS RH
; C(JOBFF) + 1 BUFFER C(JOBFF) +1
; + 0(BUFFER SIZE+2) SIZE + 1(BUFFER SIZE+2)
; C(JOBFF) +1 BUFFER C(JOBFF) +1
; +1(BUFFER SIZE+2) SIZE + 2(BUFFER SIZE+2)
; . . .
; . . .
; . . .
; C(JOBFF) + 1 BUFFER C(JOBFF) + 1
; + (N-2)(BUFFER SIZE+2) SIZE +(N-1)(BUFFER SIZE+2)
; C(JOBFF) + 1 BUFFER C(JOBFF) + 1
; + (N-1)(BUFFER SIZE+2) SIZE
;THEN SET T3:=IOUSE,C(JOBFF) + 1
; AND JOBFF:=C(JOBFF) + N(BUFFER SIZE + 2)
; P2 IS RESTORED.
BUFCLC::
IFN FTVM,<
HRRZ T1,T2 ;ADDRESS OF BUFFER HEADER
PUSHJ P,UADRCK ;GET PAGE IN CORE IF IT ISN'T
>
PUSHJ P,SAVE4## ;SAVE P1-P4
LDB P3,PBUFSZ## ;T1=BUFFER SIZE
HRRZ P1,JOBFF##(R) ;P1:=FIRST FREE LOCATION + 1
ADDI P1,1
HRRZ P2,P1
IFN FTKA10,<
HRLI P1,R
>
HRL P2,P3 ;P2:=BUFFER SIZE,FIRST FREE LOC + 1
ADDI P3,2 ;P3:=BUFFER SIZE + 2
HRRZ T2,M ;T2:=N=ADDRESS FIELD OF AC UUO
SKIPN T2 ;SEE IF DEFAULT
PUSHJ P,DFTNB ;YES, GET DEFAULT
HRR M,T2
MOVE P4,T2 ;PUT NO OF BUFFERS IN P4
HRRZ T1,P3 ;BUFFER SIZE+2
IMUL T1,T2 ;TIME NO. OF BUFFERS
ADDI T1,(P2) ;ADD LOC OF FIRST BUFFER
SUBI T1,2 ;READ JUST FOR USRREL
TLZE T1,-1 ;CHECK IF OVER 256K
PJRST ADRERR## ;DON'T ALLOW
IFN FTVM,<
CAMG T1,.UPMP+.UPREL ;CHECK AGAINST VM USRREL
JRST BUFC1 ;ALREADY ENOUGH CORE FOR BUFFERS
SKIPE .UPMP+.UPREL ;IS THIS A VM USER?
JRST BUFC0 ;YES, MORE CORE REQUIRED
>
CAMG T1,USRREL## ;WILL THIS SPACE FIT IN USER CORE?
JRST BUFC1 ;YES, FO DO INBUF CODE
; NO, AUTOMATICALLY EXPAND SIZE OF USER CORE
BUFC0: PUSH P,M ;SAVE A BUNCH OF ACS USED IN CORE AND IO WAIT
PUSH P,F
PUSH P,T4
PUSH P,T1 ;SAVE HIGHEST USRADR TO TRY FOR
PUSHJ P,IOWAIT ;CALL IOWAIT BEFORE CORUUO TO
;REDUCE MAX PDL EXCURSION
MOVE T1,(P) ;HIGHEST USER ADR TO TRY FOR
PUSHJ P,CHGCOR## ;TRY TO ASSIGN CORE
JFCL ;ERROR RETURN-LET ADR CHECK HAPPEN AND STOP JOB
POP P,T1
POP P,T4
POP P,F
POP P,M
MOVE S,DEVIOS(F) ;CHGCOR MAY HAVE ALLOWED S TO BE CHANGED
BUFC1:
IFN FTVM,<
MOVE T2,T1 ;TOP ADDRESS
HRRZ T1,P2 ;FIRST ADDRESS
PUSHJ P,LRNGE## ;MAKE SURE ALL PAGES ARE IN CORE
>
BUFC2: ADD P2,P3 ;P2:=C(P2) + C(P3)
HRRZ T1,P1 ;IS LAST ADDR IN BOUNDS?
PUSHJ P,UADRCK
EXCTXU <MOVEM P2,@P1> ;BUFFER HEADER+1:=C(P2)
HRR P1,P2 ;P1 18-35:=C(P2 18-35)
SOJG P4,BUFC2 ;N:=N-1. IS N GR 0?
HRR P2,JOBFF##(R)
ADDI P2,1
MOVEI T1,-2(P1) ;CHECK LAST ADR. OF HEADER
PUSHJ P,UADRCK
SUB P1,P3
IFN FTMSGSER,<
MOVE T4,P1 ;T4 = ADDRESS OF LAST BUFFER
> ;END FTMSGSER
EXCTXU <MOVEM P2,@P1> ;LINK LAST BUFFER TO FIRST BUFFER
ADDI P1,-1(P3)
HRRM P1,JOBFF(R) ;JOBFF:=C(JOBFF)+1+N(BUFFER SIZE+2)
HRRZ T3,P2 ;T3:=IOUSE,ADDRESS OF FIRST BUFFER
; IN RING.
HRLI T3,IOUSE
POPJ P, ;RETURN
;SUBROUTINE TO COMPUTE DEFAULT NO OF BUFFERS
;RETURNS NUMBER IN T2, RESPECTS T1,T3
DFTNB: MOVEI T2,2 ;ASSUME NOT A DISK
MOVSI T4,DVDSK
TDNE T4,DEVMOD(F) ;IS IT?
MOVE T2,NUMBF## ;YES
POPJ P, ;RETURN WITH ANSWER
;ROUTINE TO CLEAR IO BUFFER IN USER AREA
;CALLED AT INTERRUPT AND UUO LEVEL, AT INTERRUPT LEVEL ONLY ON KA10
;CALL: HRRZ T1,REL. ADR. OF 2ND WORD OF USER BUFFER
; PUSHJ P,BUFCLR
; ERROR RETURN MEMORY EXCEEDED
; EXIT RETURNS HERE IF MEMORY NOT EXCEEDED
; CLEARS THE WORD COUNT AND DATA AREA OF THE BUFFER WHOSE ADDRESS
; IS IN T1 18-35.
BUFCLR::
IFE FTVM,<
PUSHJ P,IADRCK ;IN BOUNDS?
POPJ P, ;NO. ERROR RETURN
IFN FTKA10,<
HRLI T1,R
>
> ;END FTVM
IFN FTVM,<
PUSHJ P,UADRCK
>
PUSH P,T1 ;SAVE FIRST BUFFER ADR.
EXCTUX <HLRZ T2,@T1> ;T2 18-35=SIZE
TRZ T2,IOUSE
JUMPE T2,TPOPJ## ;WORD COUNT=0 IS ILLEGAL
IFE FTVM,<
ADD T1,T2 ;LAST ADR=2ND ADR+SIZE
TLZ T1,-1 ;CLEAR LEFT HALF
PUSHJ P,IADRCK ;LAST ADDRESS IN BOUNDS?
JRST TPOPJ## ;NO. ERROR RETURN
>
IFN FTVM,<
ADD T2,T1
PUSHJ P,LRNGE##
MOVE T1,T2
>
HLL T1,(P) ;SET LAST ADR. FOR RELOC.
POP P,T2 ;RESTORE FIRST ADR.
NOSHUFF ;NO SHUFFLING
MOVEI T2,@T2 ;ABS. ADR. OF 2ND WORD OF BUFFER
HRL T2,T2
AOBJN T2,.+1 ;THIRD WORD IN BUFFER
EXCTXU <SETZM (T2)> ;CLEAR THIRD WORD
AOS T2 ;SET DEST. ADR. TO 4TH WORD
EXCTUU <BLT T2,@T1> ;CLEAR BUFFER
SHUFFLE ;SHUFFLING
JRST CPOPJ1## ;SUCESSFUL RETURN
SUBTTL RANDOM SUBROUTINES FOR I/O
;ROUTINE TO COMPUTE 12 BIT FOLDED CHECKSUM
;CALL: PUSHJ P,CKS12
; EXIT ALWAYS RETURNS HERE
;CALCULATES FOLDED 12 BIT CHECKSUMS OF THE DATA WORDS IN THE
;BUFFER WHOSE ADDRESS IS IN AC T2.
;ON RETURN, THE LEFT HALF OF AC T1 CONTAINS A CHECKSUM OBTAINED
;BY ACCUMULATING, IN ONE'S COMPLEMENT, THE DATA WORDS AND FOLDING IT.
;AC T2 CONTAINS A 1.
CKS12:: AOS T2 ;T2:=-WORD COUNT,ADDRESS OF FIRST DATA WORD
HRRZ T1,0(T2)
MOVNS T1
AOS T2
HRL T2,T1
CLEARM T1 ;INITIALIZE TWO'S COMPLEMENT SUM
CKS12A: ADD T1,0(T2) ;TWO'S COMPLEMENT ADD
AOBJN T2,CKS12A ;DONE?
LSHC T1,-30
LSH T2,-14
ADD T1,T2
LSHC T1,-14
LSH T2,-30
ADD T1,T2
TRZE T1,770000
AOS T1
HRLZS T1
MOVEI T2,1 ;T2:=1
POPJ P,
REPEAT 0,<
;ROUTINE TO CLEAR RESIDUE OF WORD POINTED TO BY A BYTE POINTER
;CALL: PUSHJ P,CLRBYT
; EXIT ALWAYS RETURNS HERE
;CALLED WITH A BYTE POINTER IN AC T1, IT CLEARS THE REST OF THE
;WORD POINTED TO BY THE BYTE POINTER.
CLRBYT::LDB T2,[POINT 6,T1,5] ;T2:=P
DPB T2,[POINT 12,T1,11] ;T1 0-5:=0,T1 6-12:=P
SETZM T2
DPB T2,T1 ;CLEAR BITS 36-P THROUGH 35
POPJ P, ;RETURN
> ;END REPEAT 0
;ROUTINE TO RELEASE ALL DEVICES ASSIGNED TO JOB
IORELS::MOVEI T1,RELEA3 ;RELEASE ALL IO DEVICES(DON'T CLOSE)
;ROUTINE TO DO IO FOR ALL DEVICES ASSIGNED TO JOB
;CALL MOVEI T1,ADR. OF IO SUB.
; PUSHJ P,IOALL
; RETURNS WITH J=CURRENT JOB # ,UUO PRESERVED
IOALL:: PUSHJ P,SAVE1## ;SAVE P1 TO PRESERVE PHYSICAL BIT
PUSH P,T1 ;SAVE ADR. OF SUB.
PUSH P,M ;SAVE M
HRRZ P1,USRHCU## ;HIGHEST CHANNEL NUMBER IN USE
CAILE P1,17 ;BIGGER THAN MAX NUMBER OF CHANNELS ?
STOPCD IOALL2,DEBUG,JAC, ;++JOB DATA AREA CLOBBERED
MOVSI M,400000 ;NEVER RETURN AN ERROR CODE
IOALL0: SKIPN F,USRJDA##(P1) ;GET NEXT DDB ADR., IS IT IN USE?
JRST IOALL1 ;NO, KEEP GOING
MOVE S,DEVIOS(F)
DPB P1,PUUOAC##
MOVE T4,DEVSER(F) ;SETUP ADR. OF DEV. DISP. TABLE
LDB T1,PJOBN## ;GET JOB NUMBER WHICH JOB IS ASSIGNED TO
CAMN T1,JOB## ;IS IT SAME AS CURRENT JOB(SHOULD BE EXCEPT FOR 140
; RESTART WHILE THIS JOB WAS SWAPPED OUT)
; DEVICE DATA BLOCKS JOB NUMBERS ARE SET TO 0 ON
; 400 RESTART,BUT THE JOB DATA AREA DEVICE ASSIGNMENTS
; FOR SWAPPED OUT JOBS HAVE NOT
PUSHJ P,@-1(P) ;YES,CALL THE SUB.
IOALL1: SOJGE P1,IOALL0 ;DECREMENT USER CHANNEL NUMBER
IOALL2: POP P,M ;RESTORE M & RETURN RESTORING T1 TOO
PUSHJ P,CPUJOB## ;GET JOB NO.
JRST TPOPJ##
;WAIT TILL ALL DEVICES ARE INACTIVE
IOWAIT::MOVEI T1,WAIT1##
JRST IOALL
;ROUTINE TO CLEAR PROTECTED JOB DATA AREA IN MONITOR
;AND RECLAIM FREE AREA ABOVE USER PROGRAM FOR IO BUFFERS
;CALL: MOVE R,ADR. OF CURRENT JOB DATA AREA
; PUSHJ P,SETUSR
SETUSR::HLRZ T1,JOBSA##(R) ;RESET FIRST FREE LOC. FOR THIS JOB
MOVEM T1,JOBFF##(R)
CLRUSR::SETZM JOBENB##(R) ;INITIALIZE APR TRAPPING (I.E., NONE)
MOVEI T1,USRLO1## ;FIRST LOC+1 TO CLEAR
HRLI T1,USRLO## ;FIRST LOC.
SETZM USRLO##
BLT T1,USRHI##
SETZM USRHCU## ;CLEAR HIGHEST USER IO CHAN. IN USE
POPJ P,
;ROUTINE TO FLAG DEVICE ACTIVE
;CALL MOVE S,IO STATUS BITS
; MOVE F,ADDRESS OF DEVICE DATA BLOCK
; PUSHJ P,SETACT
;CALLED BY ALL IO SERVICE ROUTINES AT UUO AND INTERRUPT LEVELS
REPEAT 0,<
ORACT: TRO S,IOACT
IORB S,DEVIOS(F)
JRST SETHNG
>
SETACT::TROA S,IOACT
CLRACT::TRZ S,IOACT
TLZ S,IOW
STOIOS::MOVEM S,DEVIOS(F)
SETHNG::LDB T1,PDVTIM## ;GET CODE FOR NO. OF SECONDS
PUSH P,T1 ;STACK THE CODE
MOVEI T1,1 ;COMPUTE 2**N-1
LSH T1,@0(P) ; ..
SUBI T1,1
DPB T1,PDVCNT## ;PUT TIME INTO THE COUNTER
IFN FTMSGSER&<FTKI10!FTKL10>&FTVM,<
MOVEI T1,DEPMSG ;LOAD UP THE MESSAGE BIT
TDNE T1,DEVMSG(F) ;CONTROLED BY MSGSER?
PUSHJ P,MPXIOS## ;YES--UPDATE IOACT IN MPX DDB
> ;END FTMSGSER&FTKI10&FTVM
JRST TPOPJ## ;RESTORE T1 AND RETURN
DEVCHK::HLRZ F,HNGLST##
DEVCK0: MOVE S,DEVIOS(F) ;IS DEVICE ACTIVE?
MOVE T4,DEVSER(F) ;DISPATCH TABLE ADDRESS
MOVE T1,DEVCHR(F) ;WORD CONTAINING DEVICE OFF-LINE BIT
TLNE T1,DVOFLN ;DID THE SERVICE ROUTINE SAY ITS ONN-LINE?
PUSHJ P,DOFL(T4) ;YES, SEE IF ITS STILL OFF-LINE
JRST DEVCK1 ;IT IS
MOVSI T1,DVOFLN ;ITS ON-LINE, CLEAR THE OFF-LINE BIT
ANDCAM T1,DEVCHR(F)
IFN FTPI,<
PUSHJ P,PSIONL## ;TELL THE USER ITS ON-LINE IF HE'S INTERESTED
>
DEVCK1: TRNN S,IOACT
JRST DEVCK2 ;NO
LDB T1,PDVCNT## ;YES,DECREMENT
SOJL T1,DEVCK2 ;0 MEANS IGNORE DEVICE
DPB T1,PDVCNT##
JUMPN T1,DEVCK2 ;HAS COUNT GONE TO 0?
PUSH P,F
PUSHJ P,DHNG(T4) ;DISPATCH TO SERVICE ROUTINES TO
; UNHANG DEVICE
PUSHJ P,DEVHNG## ;PRINT ERROR MESSAGE AND STOP JOB
POP P,F ;DO NOT PRINT MESS. AND STOP JOB RETURN
DEVCK2: HLRZ F,DEVSER(F)
JUMPN F,DEVCK0
POPJ P,
;ROUTINE TO SETUP R AND J FOR INTERRUPT SERVICE ROUTINE
;CALL PUSHJ P,IOSET
; EXIT ALWAYS RETURNS HERE
;THIS PROGRAM IS CALLED FROM AN INTERRUPT SERVICE ROUTINE.
;IT PUTS THE ADDRESS OF THE DATA AREA OF THE JOB (C(JBTADR18-35))
;CONNECTED TO THE DEVICE SPECIFIED BY AC F IN AC R AND
;PUTS THE J POINTER (C(DEVCTR)) IN AC ITEM.
IOSET:: LDB R,PJOBN##
MOVE J,DEVCTR(F) ;J:=J POINTER=C(DEVCTR)
MOVE R,JBTADR##(R) ;R:=C(JBTADR 18-35)
MOVE S,DEVIOS(F) ;GET IO STATUS FROM THE DDB
POPJ P, ;RETURN
;CALLING SEQUENCE
; PUSHJ P,IOSETC
; EXIT ALWAYS RETURNS HERE
;SETS JBFPTR18-35:=C(T2 18-35)
; JBFCTR:=C(J)*[WORD LENGTH/BYTE SIZE]
;WHERE WORD LENGTH:=36 DECIMAL
; BYTE SIZE:=C(JBFPTR6-11)
; [X]:= INTEGER PART OF X
IOSETC::ADDI U,1 ;JBFPTR12-18:=0
HRLZI T1,7777 ;JBFPTR18-35:=C(T2 18-35)+1
EXCTUU <ANDM T1,@U>
EXCTUU <HRRM T2,@U>
EXCTUU <AOS @U>
TLNN S,IO ;DO THINGS DIFFERENTLY ONLY ON INPUT.
LDB T1,PIOMOD ;I/O MODE
CAIE T1,PIMMOD ;COUNT BYTES FOR PIM OR BYTE
CAIN T1,BYTMOD ;BYTE MODE?
SOJA U,IOSET2 ;YES, BACKUP U TO POINT AT 1ST WORD OF THE HEADER
EXCTUX <LDB T2,[POINT 6,@U,11]> ;T2:=BYTE SIZE
PUSHJ P,ITMCT1 ;JBFCTR:=C(J)*[36/BYTE SIZE]
IOSET1: ADDI U,1
EXCTXU <MOVEM J,@U>
POPJ P, ;EXIT
;HERE IF BYTE MODE I/O, STORE BYTE COUNT COMPUTED BY THE SERVICE ROUTINE
IOSET2: EXCTUX <MOVE T1,@U> ;POINTER TO THE CURRENT BUFFER
HLL T1,U ;RELOCATE
ADDI T1,1 ;POINT AT THE COUNT WORD IN THE BUFFER
EXCTUX <MOVE J,@T1> ;GET THE BYTE COUNT FROM THE BUFFER
AOJA U,IOSET1 ;STORE IT IN THE USER'S RING HEADER
;ROUTINE TO SET UP CONDITIONS FOR RETURN FROM INTERRUPT LEVEL ON
;DEVICE ERROR (UNIT RECORD)
;SERVICE ROUTINES USING THIS FACILITY MUST FOLLOW THE FOLLOWING PROTOCOL
;A. AT INTERRUPT LEVEL,
; IF NO ERROR AT END OF DATA: CLEAR IOSTBL IN LH(S)
; IF ERROR:
; 1. STOP DEVICE
; 2. PUSHJ P,DEVERR
; 3. SET INTERNAL FLAGS TO REMEMBER ERROR CONDITION TO EFFECT
; RESTART AT A LATER TIME
; 4. DISMISS INTERRUPT
;B. AT UUO LEVEL ENTRANCES THE FOLLOWING MUST BE DONE
; 1. INIT/RELEASE - RESET INTERNAL ERROR FLAGS
; 2. INPUT/OUTPUT - IF ERROR FLAGS (INTERNAL) SET:
; A. CALL HNGSTP
; B. SEE IF DEVICE OK NOW (CALL HNGSTP AGAIN IF NOT)
; C. SET DEVICE FOR RESTART FROM INFO SAVED IN INTERNAL FLAGS
; AND RESET FLAGS
; NOTE: IOSTBL WILL ALWAYS BE CLEARED AT UUO ENTRANCE TO SERVICE ROUTINE
; IF NO ERROR FLAGS SET, NORMAL EXECUTION
DEVERR::TLO S,IOSTBL ;SET ERROR FLAG
IFN FTMSGSER,<
MOVEI T1,DEPMSG ;CONTROLLED BY MSGSER ?
TDNN T1,DEVMSG(F)
JRST DEVER1 ;NO
PUSH P,F
HRRZ F,DEVXTR(F) ;YES, GET THE MPX DDB
MOVSI T1,IOSTBL
IORM T1,DEVIOS(F) ;LITE TROUBLE THERE ALSO
POP P,F ;RESTORE F
DEVER1:>
;IN I/O WAIT?
PUSHJ P,SETIOD## ;YES - WAKE UP
IFN FTKI10!FTKL10,<
PUSHJ P,RTEVM## ;RETURN EVM IF ANY
>
PJRST CLRACT ;CLEAR I/O ACTIVE AND RETURN
;ROUTINE TO RETURN NO. OF ITEMS IN BUFFER
;CALL: PUSHJ P,ITMSET
; EXIT ALWAYS RETURNS HERE
;SETS AC J:=(BUFFER SIZE-1)*[WORD LENGTH/BYTE SIZE]
;WHERE BUFFER SIZE:=BITS 1-17 OF THE BUFFER HEADER WORD POINTED TO
; BY C(DEVADR)
; WORD LENGTH:=36 DECIMAL
; BYTE SIZE:=INTEGER PART OF X.
;CALLING SEQUENCE
; PUSHJ P,ITMCNT
; EXIT ALWAYS RETURNS HERE
;SETS AC J:=C(J)*[WORD LENGHT/BYTE SIZE]
;CALLING SEQUENCE
; PUSHJ P,ITMCT1
; EXIT ALWAYS RETURNS HERE
;SETS AC J:=C(J)*[WORD LENGHT/C(T2)]
ITMSET::LDB J,[POINT 17,@DEVADR(F),17];J:=BUFFER SIZE-1
SUBI J,1
ITMCNT::LDB T2,[POINT 6,DEVPTR(F),11];T2:=BYTE SIZE
ITMCT1::MOVEI T1,44 ;J:=C(J)*[WORD LENGTH/C(T2)]
IDIV T1,T2
IMUL J,T1
POPJ P,
;ROUTINE TO SET DEVICE STATUS WORD FROM UUO
;AND SETUP S
SETIOS::PUSHJ P,WAIT2 ;WAIT FOR DEVICE (INCLUDING TTY MONITOR COMMAND
; RESPONSE WHEN USER INITS TTY)
PUSHJ P,CHKMOD ;CHECK FOR LEGAL MODE, IF NOT RIGHT DONT RETURN
TRZ M,IOACT ;LET USER SET ALL BITS EXCEPT IOACT
HRRM M,DEVIOS(F)
POPJ P,
;CHECK FOR A LEGAL MODE FOR DEVICE
CHKMOD: LDB T2,[POINT 4,M,35] ;GET DEVICE DATA MODE
MOVEI T1,1 ;AND CHECK FOR LEGALITY
LSH T1,(T2)
TDNE T1,DEVMOD(F)
POPJ P, ;OK
PUSHJ P,TTYKLQ## ;DISCARD DDB IF IT WAS A FREE TTY
JRST ILLMOD## ;AND GIVE ILLEGAL MODE ERROR
;CHKPIM CHECKS WHETHER A DEVICE IS INITED IN PACKED IMAGE MODE
;IT GIVES 2 RETURNS:
;1 NORMAL RETURN DEVICE IS INITED IN PIM MODE
;2 SKIP RETURN DEVICE IS NOT INITED IN PIM MODE
CHKPIM::PUSH P,T1 ;SAVE T1
LDB T1,PIOMOD## ;LOAD THE MODE
CAIN T1,PIMMOD ;ENABLED IN PIM MODE
JRST TPOPJ ;YES GIVE NON SKIP RETURN
JRST TPOPJ1 ;NO GIVE SKIP RETURN
;SETUP BYTE POINTER AND ITEM COUNT
;CALL PUSHJ P,NEWBUF
; ADDRESS CHECK WHEN SETTING UP BUFFER
; OK RETURN
NEWBUF::HRRZ T1,DEVADR(F) ;T1:=INPUT BUFFER HEADER ADDRESS
IFN FTKI10!FTKL10,<
SKIPN DEVEVM(F) ;DOES THIS DDB HAVE EVM?
STOPCD .,STOP,NEV, ;++NO EVM
HLRZ T2,(T1) ;BUFFER SIZE
TRZ T2,IOUSE ;CLEAR USE BIT
ADDI T2,(T1) ;LAST WORD TO CLEAR
HRLS T1 ;MAKE A BLT POINTER
AOBJN T1,.+1
SETZM (T1) ;ZERO THE FIRST WORD OF THE BUFFER
AOS T1
BLT T1,(T2) ;ZERO THE BUFFER
>
IFN FTKA10,<
NEWBF2: PUSHJ P,BUFCLR ;CLEAR INPUT BUFFER.
POPJ P, ;ADDRESS CHECK
>
NEWBF3: HRLZI T1,7737
AND T1,DEVPTR(F) ;DEVPTR 0-5:=0, DEVPTR 12:=0
HRR T1,DEVADR(F) ;DEVPTR 18-35:=C(DEVADR 18-35) + 1
AOS T1
MOVEM T1,DEVPTR(F)
PUSHJ P,ITMSET ;J:=(BUFFER SIZE-1)*[36/BYTE SIZE]
MOVEM J,DEVCTR(F) ;DEVCTR:=ITEM COUNT
JRST CPOPJ1## ;RETURN
;ROUTINE TO SETUP BYTE POINTER ACCORDING TO DATA MODE
;CALL: PUSHJ P,SETBYT
; EXIT ALWAYS RETURNS HERE
;SETS T1 0-5:=0
; T1 6-11:=S
; T1 12-13:=0
; T1 14-17:=R
;WHERE S=36 IF DATA MODE (S 32-25) IS BINARY (B)
; IMAGE (I), IMAGE BINARY (IB), OR DUMP (SD,D,DR)
; S=7 IF DATA MODE IS ASCII PACKED (A)
; ASCII LINE (AL)
; ASCII SEQUENCED (AS)
; ASCII SEQUENCED LINE (ASL)
; OR ALTERNATE MODE BREAK (AM)
;CLOBBERS T2
SETBYT::HRLI T1,PBYTMD## ;ASSUME BYTE MODE
LDB T2,PIOMOD## ;GET MODE FROM S
CAIN T2,BYTMOD ;IS IT ?
POPJ P, ;YES, RETURN
TRNN S,14 ;IS MODE LESS THAN 10?
HRLI T1,PASCII## ;YES,ASCII OR ASCII LINE
TRNE S,14 ;10 OR GREATER?
HRLI T1,PIMAGE## ;YES, IMAGE,IMAGE BIN. OR BIN.
PUSHJ P,CHKPIM ;PACKED IMAGE MODE CHECK
SKIPA ;YES
POPJ P, ;NO
LDB T2,PDVTYP## ;PIM, IS IT TTY
CAIE T2,<.TYMPX/.TYEST> ;ALLOW PIM ON MPX
CAIN T2,<.TYTTY/.TYEST> ;TEST
HRLI T1,PIMTTY## ;YES
POPJ P,
;ROUTINE TO STORE DATA IN IOBUFFER FOR INPUT CHAR. AT A TIME DEVICES
;CALL: PUSHJ P,STODAT
; EXIT1 CHECKSUM ERROR
; EXIT2 BLOCK FULL OR BLOCK COMPLETE
; EXIT3 DATA STORED CORRECTLY
;CALLED FROM AN INPUT SERVICE ROUTINE WITH A DATA J IN AC DAT.
;STORES THE DATA J IN THE BUFFER, CHECKING TO SEE IF IT WERE
;THE FIRST J ON THE BUFFER AND SETTING UP THE POINTER AND
;WORD COUNT APPROPRIATELY CHECKING THE MODE TO SEE IF ANY SPECIAL
;PROCESSING NEED BE DONE. FOR EXAMPLE, THE TERMINATION
;OF A BUFFER ON CERTAIN CHARACTERS IN OTHER MODES, OR IF THE BUFFER
;IS FULL. THERE ARE THREE RETURNS FROM THIS ROUTINE: THE FIRST
;RETURN OCCURS ON AN ERROR CONDITION, THE SECOND RETURN OCCURS
;ON A BLOCK FULL CONDITION OR BLOCK COMPLETE CONDITION, THE THIRD
;RETURN OCCURS ON THE DATA STORED CORRECTLY CONDITION. THIS
;ROUTINE ALSO DOES SOME CHECKING ON INPUT OF BINARY RECORD,
;PAPER TAPE OR CARDS.
;CALLING SEQUENCE
; PUSHJ P,STOSQD
; XXXX ALWAYS SKIPS
; EXIT ALWAYS RETURNS HERE
;STORES THE WORD COUNT:=C(DEVPTR 18-35) -C(DEVIAD 18-35) - 1
;IN THE BUFFER.
STODAT::TLNN S,IOFST ;IS THIS FIRST J OF BUFFER?
JRST STO0 ;NO
PUSHJ P,NEWBUF ;SET UP A NEW BUFFER. J:=(BUFFER
; SIZE - 1)*[36/BYTE SIZE]
POPJ P,
STO0: LDB T2,PIOMOD## ;DATA MODE
CAIN T2,B ;MODE=BINARY?
JRST STOBIN
TLZ S,IOFST
STO1: IDPB U,DEVPTR(F) ;STORE DATA IN BUFFER.
CAIE T2,A ;MODE=ASCII, IMAGE, OR BINARY?
CAIN T2,I
JRST STOAIB
CAIE T2,IB ;IMAGE BINARY?
CAIN T2,B ;CHECKSUM BINARY?
JRST STOAIB ;YES
ANDI U,177 ;NO, MUST BE ASCII LINE MODE.
CAIG U,14 ;LINE FEED,FORM FEED, OR VERTICAL TAB?
CAIGE U,12
JRST .+2 ;NO
JRST STOSQF ;YES
SOJGE J,CPOPJ2## ;J:=C(J)-1. IS C(J) GR OR=0?
STOE1: TRO S,IOBKTL ;IOBKTL:=1
POPJ P,
STOAIB: SOJG J,CPOPJ2##; J:=C(J)-1. IS C(J) GR 0?
CAIN T2,A ;MODE=ASCII?
JRST STOSQF ;YES
CAIN T2,B ;MODE=BINARY?
JRST STOBND ;YES, COMPUTE CHECKSUM AND CHECK.
PUSHJ P,ITMSET ;J:=(BUFFER SIZE-1)*[36/BYTE SIZE]
; - C(DEVCTR)
SUB J,DEVCTR(F)
MOVE T2,DEVIAD(F) ;STORE ITEM COUNT
ADDI J,1 ;IN FIRST WORD OF BUFFER
AOJA T2,STOSQE
STOSQD::TLZN S,IOFST ;FIRST CALL?
JRST STOSQF ;NO
PUSHJ P,NEWBUF ;YES, CLEAR BUFFER,SET ITEM COUNT
POPJ P, ;ADDRESS CHECK
STOSQF: MOVE T2,DEVIAD(F) ;REL. ADR. OF BUFFER
AOS T2
HRRZ J,DEVPTR(F) ;J:=C(DEVPTR 18-35) -
; C(DEVIAD 18-35) -1
SUBI J,(T2)
STOSQE: HRRM J,@T2 ;WORD COUNT TO FIRST WORD IN BUFFER
JRST CPOPJ1## ;EXIT2. BLOCK COMPLETE
STOBIN: TLZN S,IOFST ;WILL THE NEXT J BE THE FIRST J
JRST STO1 ;OF A BUFFER? IOFST:=0
HRRZ T1,U ;YES.
CAMLE T1,J ;IS WORD COUNT LE (BUFFER SIZE-1)*
JRST STOE1 ; [36/BYTE SIZE]?
MOVE J,T1 ;J:=WORD COUNT
MOVEM U,@DEVPTR(F) ;STORE WORD COUNT IN BUFFER
JRST CPOPJ2## ;EXIT3. DATA STORED CORRECTLY.
STOBND: MOVEI T2,@DEVIAD(F)
PUSHJ P,CKS12 ;COMPUTE CHECKSUM
ADD T2, DEVIAD(F)
HLLZ T2,@T2 ;DATA CHECKSUM=COMPUTED CHECKSUM?
CAMN T1,T2
JRST CPOPJ1## ;EXIT2. BLOCK COMPLETE
TRO S,IODTER ;IODTER:=1
POPJ P, ;EXIT1. CHECKSUM ERROR
XLIST
$LIT
LIST
UUOEND::END