Trailing-Edge
-
PDP-10 Archives
-
AP-D543V_SB
-
core1.mac
There are 6 other files named core1.mac in the archive. Click here to see a list.
TITLE CORE1 - LOGICAL AND PHYSICAL CORE ALLOCATION ROUTINES - V1547
SUBTTL T. HASTINGS/TH/RCC/CHW/JMF/DAL 2 AUG 77
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 VCORE1,1547
;THIS MACRO PUTS VERSION NO. IN STORAGE MAP AND GLOB
ENTRY CORE1 ;ALWAYS LOAD CORE1(FOR LIB SEARCH)
;CORE ALLOCATION IS DONE ON A 1K BLOCK BASIS
;USING A USE BIT TABLE(CORTAB). EACH 1K BLOCK IS REPRESENTED BY A 1 OR 2
;BIT ENTRY IN CORTAB (2 BITS IF THE LOCK UUO IS INCLUDED IN THE SYSTEM)
;A ZERO ENTRY MEANS BLOCK NOT IN USE
;A NON-ZERO ENTRY INDICATES MEMORY IN USE AS FOLLOWS:
;(NUMBERS IN BRACKETS INDICATE CONTENTS OF ENTRIES IN CORTAB IN THE FOLLOWING FORMAT
;[CONTENTS OF CORTAB IN SYSTEM NOT INCLUDING LOCK UUO, CONTENTS OF CORTAB
;IN SYSTEM INCLUDING LOCK UUO]
; 1. IN USE BY MONITOR [1,2]
; 2. IN USE BY A LOCKED JOB [-,2]
; 3. IN USE BY A JOB NOT LOCKED [1,1]
; 4. NON-EXISTANT [1,2]
;WHEN THE SYSTEM IS STARTED, SYSINI SETS THE CORTAB TABLE
;IT ALSO SETS A BYTE POINTER(CORLST) WHICH POINTS TO THE
;LOWEST NON-EXISTANT BLOCK IMMEDIATELY ABOVE THE HIGHEST
;EXISTANT BLOCK. IT ALSO SETS CORTAL TO THE NO. OF
;FREE BLOCKS AVAILABLE.
;THE CORE1 ROUTINE ASSIGNS CORE IF POSSIBLE, SETS THE USE BITS,
;AND MOVES THE JOB IF NEW ASSIGNMENT IS A DIFFERENT PLACE THAN OLD
;THE JBTADR TABLE IS ALSO UPDATED BY THE CORE ROUTINES
;LH=PROTECTION,RH=RELOCATION
;JOBADR IS MODIFIED IF CORE FOR CURRENT JOB
;HARDWARE RELOC. AND PROTEC. ARE RESET IF CURRENT JOB
;FINALLY JOBREL(PROTECTION) IN JOB DATA AREA IS ALWAYS UPDATED
;LIST OF GLOBALS AFFECTED:
;JBTADR,CORTAL,CORTAB,HOLEF,SHFWAT,JOBADR,HOLES
;CORE UUO
;CALL: MOVEI AC,HIGHEST REL. ADR. DESIRED IN LOW SEG
; HRLI AC,HIGHEST REL. ADR. DESIRED IN HIGH SEG
; CALL AC,[SIXBIT /CORE/]
; ERROR RETURN
; OK RETURN TO USER, JOB MOVED IF NECESSARY
;RETURN NO. OF FREE 1K BLOCKS IN AC(OR MAX. NO. BLOCKS ALLOWED IF SWAPPING SYS)
;BOTH HALVES 0 MEANS ERROR RETURN NO. OF FREE 1K BLOCKS(OR MAX. NO. OF BLOCKS
; ALLOWED IF SWAPPING SYSTEM) IMMEDIATELY WITHOUT AFFECTING CORE
; OR WAITING FOR IO DEVICES
;LH=0 MEANS DO NOT CHANGE HIGH SEG ASSIGNMENT
;RH=0 MEANS DO NOT CHANGE LOW SEG ASSIGNMENT
EXTERN JOB,CORTAL,PAGSIZ,PG.BDY,W2PLSH,P2WLSH,JBTSTS
EXTERN ESTOP1,IOWAIT,SETREL,STOTAC,WSCHED
CORUUO::SKIPE T1 ;IF ZERO CORE REQUESTED JUST RETURN
; THE AMOUNT AVAILABLE
PUSHJ P,CHGCOR ;CHANGE THE CORE ASSIGNMENT
SKIPA ;NOT ENOUGH
AOS (P) ;OK RETURN TO USER
IFE FTSWAP,<
MOVE T1,CORTAL ;RETURN NO. OF FREE 1K BLOCKS (COUNTING
> ; DORMANT AND IDLE SEGMENTS AS FREE)
IFN FTSWAP,<
PUSHJ P,CORBND ;T1 = UPPER BOUND ON WORDS FOR JOB
LSH T1,W2KLSH## ;CONVERT TO K
>
JRST STOTAC ;STORE IN USER AC AND RETURN TO USER
;SUBROUTINE TO CHANGE CORE - JUST LIKE CORE UUO
; EXCEPT VALUE NOT STORED IN USER'S UUO ACS
; USED BY MONITOR JOBS INSTEAD OF CORE UUOS
;CALL: MOVE T1,XWD NEW HIGH, NEW LOW SEG HIGHEST ADR
; PUSHJ P,CHGCOR
; ERROR RETURN
; OK RETURN
CHGCOR::PUSHJ P,SAVE4## ;SAVE P1-P4
PUSH P,T1 ;NO, SAVE HIGHEST DESIRED ADDRESS IN BOTH SEGS
IFN FTVM,<
MOVSI T2,JACCT
TDNE T2,JBTSTS##(J) ;PRIVILEGED PROGRAM?
TLO P1,PHONLY ;YES, PHYSICAL ONLY THEN
>
PUSHJ P,IOWAIT ;WAIT FOR ALL DEVICE INACTIVE
HRRZ T1,(P) ;HIGHEST REL. LOC. DESIRED FOR LOW SEG(RH)
JUMPE T1,CORU1 ;IS RH 0(IF YES DO NOT CHANGE LOW SEG)?
IORI T1,PG.BDY ;NO, MAKE IT AN EVEN MULTIPLE OF 1K-1
IFN FTLOCK,<
MOVSI T2,NSHF!NSWP ;LOCKED JOBS CANNOT CHANGE THEIR SIZE
TDNN T2,JBTSTS(J) ;IS HE LOCKED?
>
PUSHJ P,CORE1 ;TRY TO ASSIGN CORE
JRST CORERR ;NOT AVAILABLE, ERROR RETURN
; SUM OF NEW LOW AND OLD HIGH SEG TOO BIG
CORU1: HLRZ T1,(P) ;CHECK TO SEE IF USER IS REQUESTING HIGH CORE
IFE FT2REL,<
CAMG T1,USRREL ;0 MEANS NO CHANGE, 1 THRU TOP OF LOW SEG MEANS
; RETURN HIGH CORE (IF ANY), ALWAYS LEGAL
> ; EVEN IF NO HIGH SEG HARD WARE OR SOFTWARE
IFN FT2REL,<
EXTERN UCORHI
PUSHJ P,UCORHI ;TRY TO ASSIGN CORE FOR HIGH SEG,
; UCORHI EXPECTS ARG ON PD LIST
JRST CORERR ;ERROR-ACTIVE IO(SAVE IN PROGRESS FOR SOME USER)
> ; OR SUM OF NEW LOW SEG AND NEW HIGH SEG TOO BIG
; OR PROTECTION FAILURE (CAN'T UPDATE)
AOS -1(P) ;SET FOR OK(SKIP) RETURN
CORERR: POP P,T1 ;REMOVE ARG FROM LIST
IFN FTSWAP,<
MOVE T1,JBTSTS(J) ;JOB STATUS WORD
TLNE T1,JXPN!SWP ;MUST LOW SEGMENT BE SWAPPED OUT TO EXPAND OR
; HIGH SEGMENT LOGICAL CORE ASSIGNED ON DISK?
PUSHJ P,WSCHED ;YES, CALL SCHEDULER TO STOP JOB
; LOW SEG MUST BE SWAPPED OUT TO EXPAND
> ; OR HIGH SEG LOGICAL CORE ASSIGNED ON DISK
POPJ P,
;SUBROUTINE TO RETURN UPPER BOUND CORE LIMIT FOR JOB IN WORDS
;CALL: MOVE J,JOB NO
; PUSHJ P,CORBND
; ALWAYS RETURN - T1 = UPPER BOUND
INTERN CORBND
CORBND:
PUSH P,T2
IFN FTLOCK,<
PUSH P,J ;SAVE JOB NUMBER
MOVSI T1,NSWP!NSHF
MOVEI T2,0
TDNE T1,JBTSTS(J) ;SEGMENT LOCKED?
PUSHJ P,SEGSIZ ;YES, GET ITS CORE SIZE
PUSH P,T2 ;SAVE CORE SIZE
MOVE J,JBTSGN##(J) ;GET HIGH SEG NUMBER
MOVEI T2,0
JUMPLE J,CRBND1 ;USING A HIGH SEG?
TDNE T1,JBTSTS(J) ; THAT IS LOCKED?
PUSHJ P,SEGSIZ ;YES, GET HIGH SEG SIZE
CRBND1: POP P,T1 ;GET BACK LOW SEG SIZE
ADD T1,T2 ;GET TOTAL SIZE THIS JOBS LOCKED CORE
LSH T1,P2WLSH
ADD T1,CORMAX ;ADD TO CORMAX TO GET APPARENT CORMAX
POP P,J ;RESTORE JOB NUMBER
>
IFE FTLOCK,<
MOVE T1,CORMAX ;GET CORMAX
>
IFN FTTLIM,<
LDB T2,JBYLCR ;GET THIS JOBS CORE LIMIT
JUMPE T2,CRBND2
LSH T2,^D9
CAMLE T1,T2 ;WE WANT
MOVE T1,T2 ; THE SMALLER OF THE TWO
CRBND2:
IFN FTVM,<
PUSHJ P,FNDPDB## ;FIND THE PDB
JRST CRBND4 ;NO LIMIT OR GUIDELINE IF NO PDB
HRRZ T2,.PDCVL##(W) ;CURRENT PHYSICAL LIMIT OR GUIDELINE
JUMPE T2,CRBND3 ;IGNORE IF NONE
TRZN T2,400000 ;LIMIT?
JUMPL P1,CRBND3 ;NO, IGNORE GUIDELINE IF PHONLY
LSH T2,P2WLSH## ;NUMBER OF WORDS
CAMLE T1,T2 ;SMALLEST YET?
MOVE T1,T2 ;NO, USE SMALLER
CRBND3: HRRZ T2,.PDMVL##(W) ;FINALLY, MAX PHYSICAL LIMIT
JUMPE T2,CRBND4
LSH T2,P2WLSH##
CAMLE T1,T2
MOVE T1,T2
CRBND4:>
> ;END FTTLIM
IFN FTLOCK,<
LSH T1,W2PLSH
CAILE T1,@CORLIM## ;CORLIM MIGHT BE EVEN SMALLER
HRRZ T1,CORLIM## ; IF SO, IT IS THE LIMIT
LSH T1,P2WLSH
>
IFN FTPDBS,< ;IF WE SWAP PDB'S
SUBI T1,PDBWDS## ;SIZE OF PDB IN WORDS
; ROUNDED UP TO PAGE SIZE
> ;END FTPDBS
IFN FTKI10!FTKL10,<
SUBI T1,UPMSZW## ;ACCOUNT FOR THE FACT THAT THE UPMP IS ALLOCATED
; FROM USER CORE. THUS, MAXIMUM SIZE A JOB
; A JOB CAN OBTAIN IS MIN (CORMAX, JOB LIMIT)-
; THE SIZE OF THE USER PAGE MAP PAGE
>
IFN FTVM,<
JUMPL P1,T2POPJ## ;RETURN IF PHYSICAL ONLY
PUSHJ P,FNDPDB##
PJRST T2POPJ## ;NO LIMITS IF NO PDB
HLRZ T2,.PDCVL##(W) ;CURRENT VIRTUAL LIMIT
LSH T2,P2WLSH## ;CONVERT TO PAGES
CAMGE T1,T2
MOVE T1,T2
>
PJRST T2POPJ## ;YES, USE SMALLER JOB LIMIT
;CORLM. UUO -- SET JOB'S CORE LIMIT
;CALL: HRLZI AC,12
; HRRI AC,LIMIT IN NO. OF WORDS
; SETUUO AC,
; ERROR
; OK
IFN FTTLIM,<
INTERN CORELM
CORELM: JUMPE T2,CORLM1
CAIG T2,MINMAX## ;GREATER THAN MIN
MOVEI T2,MINMAX ;YES--USE MINMAX
ADDI T2,PG.BDY## ;ROUND UP TO LAST LOWSEG ADDRESS
; + HIGH SEG SIZE
;THIS IS TO BE SIMILAR TO CORE UUO
TLNE T2,-1 ;SEE IF OVERFLOW
SETOM T2 ;YES--SET TO INFINITY
LSH T2,-^D9 ;CONVERT TO 512 UNITS
CORLM1: DPB T2,JBYLCR## ;STORE
JRST CPOPJ1 ;RETURN
>
;ROUTINE TO TEST FOR ANY ACTIVE DEVICES
;CALL: MOVE J,JOB NUMBER OR HIGH SEG NUMBER
; MOVE R,ADDRESS OF JOB DATA AREA
; PUSHJ P,ANYACT
; DEVICES ACTIVE
; DEVICES NOT ACTIVE EXCEPT POSSIBLY TTY
;IN REENTRANT SYSTEMS ANYACT IS BROKEN INTO 2 CALLS, ANYSAV AND ANYDEV
;ANYSAV TESTS WHTETHER THIS IS A HI SEG THAT HAS A SAVE IN PROGRESS
INTERN ANYACT,ANYDEV
EXTERN JOBMAX,SAVE3
ANYACT:
IFN FT2REL,<
EXTERN ANYSAV
PUSHJ P,ANYSAV ;IS A SAVE IN PROGRESS FOR HI SEG?
POPJ P, ;YES - RETURN
>
ANYDEV: PUSHJ P,SAVE3 ;PRESERVE ACCUMULATORS P1, P2, P3
ANYDV1:
IFN FTMS,< EXTERNAL ANYRUN
PUSHJ P,ANYRUN ;IS THIS JOB RUNNING ON THE SLAVE
POPJ P, ;YES, RETURN IMMEDIATELY
>
IFN FT2REL,<
CAILE J,JOBMAX ;YES, IT THIS A HIGH SEG?
JRST CPOPJ1 ;YES, OK TO SHUFFLE OR SWAP SINCE NSHF,NSWP NOT SET
; AND NO SAVE IN PROGRESS
>
LDB P1,PJBSTS## ;JOB'S QUEUE CODE
IFN FTVM,<
CAIE P1,PIOWQ## ;IN PAGING I/O WAIT?
>
CAIN P1,DIOWQ## ;OR DSK I/O WAIT?
POPJ P, ;YES, CAN'T SWAP IT OUT NOW
; ONLY HAPPENS IF LOCK IS TRYING
; TO FORCE THIS JOB OUT
MOVEI P1,USRJDA ;ASSUME JOB IS CURRENT JOB (DEVICE TABLE IS THE MONITOR)
CAMN J,.C0JOB## ;IS IT?
JRST ANYDV2 ;YES
IFN FTKI10!FTKL10,<
PUSHJ P,SVEUB## ;NO, MAKE THE JOB DATA AREA ADDRESSABLE
>
MOVEI P1,JOBJDA(R)
ANYDV2: MOVEI S,IOACT ;IO DEVICE ACTIVE BIT
HRRZ P2,JOBJMH(P1) ;GET NO. OF USER IO CHANNELS IN USE
; FOR JOB(EITHER FROM JOB DATA AREA
; OR FROM MONITOR (IGNORE LH WHICH MAY BE-1
; IF SAVGET IN PROGRESS)
TLO P1,P2 ;SET TO ADD P1 TO P2
IFE FTMSGSER,<
ANY: SKIPE F,@P1 ;IS A DEVICE ASSIGNED TO THIS CHANNEL?
TDNN S,DEVIOS(F) ;YES, IS IT ACTIVE?
> ;END FTMSGSER
IFN FTMSGSER,<
ANY: SKIPN F,@P1 ;IS THERE A DEVICE ASSIGNED?
JRST ANY2 ;NO--LOOK AT NEXT CHAN.
TLZ F,-1 ;CLEAR FLAGS
CAIG P2,17 ;TOO MANY CHANS
CAML F,SYSSIZ##
STOPCD .,STOP,JJW, ;++JOB JDA WRONG
LDB P3,PDVTYP## ;GET THE DEVICE TYPE
CAIE P3,<.TYMPX/.TYEST> ;MPX?
JRST ANY1 ;NO--JUST LOOK AT IOACT
PUSHJ P,MPXACT## ;SEE IF IT IS ACTIVE
POPJ P,0 ;RETURN IF ACTIVE
JRST ANY2 ;LOOK AT NEXT DEVICE
ANY1: TDNN S,DEVIOS(F) ;IS DEVICE ACTIVE?
> ;END FTMSGSER
ANY2: SOJGE P2,ANY ;NO, KEEP LOOKING
JUMPL P2,ANY3 ;YES, FINISHED YET?
MOVSI P3,DVTTY ;DEVICE IS A TTY BIT
TDNN P3,DEVMOD(F) ;NOT FINISHED, IS DEVICE TTY?
POPJ P, ;NO, ERROR RETURN, CANNOT ASSIGN CORE
JRST ANY2 ;YES, KEEP LOOKING FOR AN ACTIVE DEVICE
ANY3:
IFN FTDHIA,<
SKIPN F,DIADSK## ;DSK CHAN STOPPED?
JRST CPOPJ1## ;NO, OK RETURN
LDB P1,PJOBN## ;YES, IS THIS THE JOB THAT STOPPED IT!
CAMN P1,J
POPJ P, ;YES, SOMETHING IS ACTIVE
>
PJRST CPOPJ1## ;OK RETURN
;ROUTINE TO FLUSH PHYSICAL CORE ASSIGNED IN MEMORY
;NOTE: THIS ROUTINE DIFERS SIGNIFICANTLY FROM CORE0 AND CORE1 IN THAT
;IT IS ONLY A PHYSICAL REMOVAL OF CORE(VIRTAL IS NOT AFFECTED)
;SEE COMMENTS FOR CORE1
;CALL: MOVE J,HIGH OR LOW SEGMENT NUMBER
; PUSHJ P,KCORE1
; ALWAYS RETURN HERE
;SCORE1 IS CALLED FROM SHUFFLER WITH T1 SET TO SEG SIZE
INTERN KCORE1,SCORE1
KCORE1: MOVEI T1,0 ;SETUP DESIRED HIGHEST ADR
SCORE1: SOS (P) ;CORE1 WILL ALWAYS SKIP RETURN
JRST CORE1A## ;BYPASS LOGICAL CORE ASSIGNMENT PART
; AND FLUSH PHYSICAL CORE(LOGICAL CORE UNEFFECTED)
;CALL: MOVE T1,HIGHEST LEGAL ASSRESSABLE LOC. DESIRED
; MOVE J,JOB NUMBER
; MOVE R,[XWD PROT.,RELOC.]=JBTADR(J)
; PUSHJ P,CORE0
; ERROR ;EITHER JOB HAS ACTIVE IO
; OR NOT ENOUGH CORE
; OK RETURN
;JOB IS MOVED IF NECESSARY TO SATISFY REQUEST
;R IS SET TO NEW CORE ASSIGNMENT ON EITHER RETURN
;0 MEANS NONE ASSIGNED IN MEMORY, ASSIGNED ON DISK
INTERNAL CORE0
INTERNAL CORE1,FTTIME,FTTRPSET,FTSWAP
EXTERNAL JOBJDA,JOB,USRJDA,JBTADR
EXTERNAL JOBPC,JBTDAT
EXTERNAL CORTAL,CORLST,HOLEF,CLRWRD
EXTERNAL CPOPJ,CPOPJ1,JOBJMH,JOBENB,JOBDPD,JOBDPG
EXTERNAL JOBPR1,CPOPJ1,JOBPRT,USRPC,CORMAX
;ENTER HERE FROM CORE CONSOLE COMMAND OR INITIAL CORE
;ASSIGNMENT OF JUST A JOB DATA AREA FOR RUN COMMAND
;IE ENTER WHEN DEVICES MAY BE ACTIVE OR JOB MAY HAVE NO PREVIOUS CORE
;JOB CAN HAVE CORE IN MEMORY, CORE ON DISK, OR NONE EITHER PLACE
;JOB CANNOT BE IN PROCESS OF SWAP OUT OR SWAP IN(CALLER'S RESPONSIBILITY)
;CORE0 NO LONGER REASSIGN CORE ON DISK IF OLD CORE ON DISK
;BECAUSE OF FRAGMENTED SWAPPING(TOO HARD) UNLESS 0 BEING ASKED FOR
;THEREFORE THE CORE COMMAND CAUSES JOB TO BE SWAPPED INTO CORE FIRST(INCORE=1)
;HOWEVER, THE R,RUN,GET,KJOB COMMANDS DO NOT REQUIRE THE PREVIOUS CORE IMAGE TO
;BE SWAPPED IN(AS THIS IS SLOW). THEY ASK FOR 140 WORDS, AND LARGER DISK SPACE IS RELINQUISHED
;UPON SWAPIN BY THE SWAPPER, VIRTAL IS INCREASED THEN RATHER THAN
;ON THE CALL TO CORE0.
;IT WILL TRY TO REASSIGN CORE IN MEMORY IF OLD CORE IN MEMORY
;IF THIS FAILS, IT WILL REASSIGN NEW CORE ON DISK AND ASK SWAPPER TO EXPAND
;IF JOB DID NOT HAVE OLD CORE, AN ATTEMPT WILL BE MADE TO ASSIGN CORE IN MEMORY
;IF THIS FAILS, TI WILL BE ASSIGNED ON THE DISK AND ASK SWAPPER TO EXPAND
;THE OTHER PLACES IN THE MONITOR WHERE THE IN-CORE COUNT IS TOUCHED IS
;IN GET WHERE IT INCREMENTS TO SHARE COPY ALREADY IN CORE.
;AND END OF SWAPIN OF LOW SEG AND HIGH SEG IS ALREADY IN CORE FOR OTHER USER
;THE CORE ROUTINES DO NOT ALTER THE HIGH SEG IN CORE COUNT. IT IS UP TO THE CALLER
;(IN SEGCON) TO CALL THE CORE ROUTINES ONLY IF IN CORE COUNT IS 0.
;AND END OF SWAPIN OF LOW SEG AND HIGH SEG IS ALREADY IN CORE FOR OTHER USER
CORE0:
IFE FTSWAP,<
JUMPE R,CORE1 ;IS JOB WITHOUT CORE IN MEMORY?
;NO
>
IFN FTSWAP,<
EXTERN IMGOUT,CPOPJ1,CHGSWP
JUMPN R,CORE0A ;DOES JOB HAVE CORE IN MEMORY?
; (ALWAYS TRUE BOTH SEGS IF CORE UUO)
IFE FT2REL,<
EXTERN CORMAX
CAML T1,CORMAX ;NO, WILL REQUEST FIT IN PHYSICAL CORE?
; COMPARE WITH LARGEST PERMITTED ADR+1(BUILD AND
; ONCE CAN RESTART CORMAX)
>
IFN FT2REL,<
EXTERN SUMSEG
PUSHJ P,SUMSEG ;NO, WILL SUM OF BOTH SEGMENTS FIT IN PHYSICAL CORE?
; LARGEST PERMITTED CORE. COMPARE SUM WITH CORMAX
>
POPJ P, ;NO, GIVE ERROR RETURN
MOVSI T2,SWP ;IS JOB SWAPPED OUT?
TDNN T2,JBTSTS(J) ;(MAY HAVE 0 DISK SPACE ALTHOUGH SWAPPED OUT)
JRST CORE1 ;NO, TRY TO ASSIGN CORE IN MEMORY
PUSHJ P,CHGSWP ;YES, CHANGE ASSIGNMENT OF SWAPPING SPACE ON DISK
; INCREASE VIRTAL(COUNT OF FREE 1K BLOCKS OF SWAPPING
; (SHOULD NEVER NEED TO DECREASE VIRTAL SINCE
; CORE COMMAND ALWAYS SWAPS JOB IN FIRST).
; (FRAGMENTATION POSTPONES RETURNING SPACE AND
; INCREASING VIRTAL UNTIL SWAP IN IF NOT ASKING
; FOR 0 VIRTUAL CORE)
JRST CPOPJ1 ;GIVE OK RETURN TO CALLER
CORE0A:
>
IFN FTTRPSET,<
EXTERN STOPTS
SKIPN STOPTS ;NO,IS TIME SHARING STOPPED BY
; TRPSET UUO DONE FOR JOB 1?
>
PUSHJ P,ANYACT ;NO,ANY ACTIVE DEVICE?
POPJ P, ;YES, CANNOT ASSIGN CORE
; NO, FALL INTO CORE1
;ROUTINE TO TRY TO ASSIGN CORE IN CORE
;LOW OR HIGH SEG MUST NOT BE SWAPPED OUT(CALLER'S RESPONSIBILITY)
;AND MUST NOT HAVE ANY ACTIVE DEVICES(IT MAY HAVE 0 CORE IN CORE THOUGH)
;IN OTHER WORDS HIGH OR LOW SEG MAY OR MAY NOT HAVE VIRTUAL CORE
;BUT IF IT HAS VIRTUAL CORE IT MUST BE IN PHYSICAL CORE
;THIS IS BOTH A LOGICAL AND A PHYSICAL CORE ASSIGNMENT
;FIRST OLD CORE IS RETURNED TO SYSTEM
;THEN NEW REQUEST IS ATTEMPTED TO BE SATISFIED IN LOWEST
;POSITION POSSIBLE. THUS CORE TENDS TO BE PACKED
;IF NEW REQUEST CANNOT BE GRANTED, OLD AMOUNT IS RETAINED, IF NON-SWAPPING SYS
;OTHERWISE SWAPPER IS CALLED(XPAND) TO EXPAND CORE BY SWAPPING OUT
EXTERN SEGSIZ
CORE1: JUMPL T1,CPOPJ## ;DON'T ALLOW NEGATIVE ARGUMENTS
IFN FTLOCK,<
MOVSI T2,NSHF!NSWP ;LOCKED SEGMENTS CANNOT CHANGE THEIR CORE SIZE
TDNE T2,JBTSTS(J) ;IS THIS SEGMENT LOCKED?
POPJ P, ;YES, ERROR RETURN
;END IFN FTLOCK
>
CAILE J,JOBMAX## ;IS THIS A HIGH SEGMENT?
JRST CORE12 ;YES, PROCEED
MOVE T3,T1 ;LOW SEGMENT, SAVE AMOUNT OF CORE REQUESTED
PUSHJ P,HSVAD## ;COMPUTE HIGH SEGMENT BOUNDS
CAIL T3,(T2) ;TRYING TO EXPAND INTO THE HIGH SEGMENT?
JUMPN T1,CPOPJ## ;YES IF THERE IS ONE - JUMP IF SO
MOVE T1,T3 ;OK, RESTORE ARGUMENT
CORE12:
NOSCHEDULE ;PREVENT SCHEDULING
IFN FTSWAP,<
EXTERN VIRTAL
PUSHJ P,SEGSIZ ;T2=OLD SEG SIZE
IFN FTKI10!FTKL10,<
JUMPE T2,CORE10
CAIG J,JOBMAX## ;IF THIS IS A LOW SEGMENT,
SUBI T2,UPMPSZ## ;SUBTRACT OUT THE SIZE OF THE UPMP WHICH WAS
; ADDED IN FOR ACCOUNTING PURPOSES
>
CORE10: SKIPN T3,T1 ;IS O BEING REQUESTED?
MOVNI T3,1 ;YES, PRETEND -1(DEPEND ON ASH BUG WHICH KEEPS -1
; ON RT. SHIFT)
ASH T3,W2PLSH ;CONVERT TO NO. OF K-1(01,0,1,2,...)
SUB T3,T2 ;NO. OF K-1 INCREASE=NEW-OLD-1
IFN FTVM,<
PUSHJ P,VIRCHK## ;ALLOCATE CORE ON DSK? (USER JUST GOING
; VIRTUAL OR ALREADY VIRTUAL)
POPJ P, ;ALREADY VIRTUAL BUT TRYING TO EXCEED LIMITS
PJRST CPOPJ1## ;YES, TAKE GOOD RETURN
PUSHJ P,SAVE1##
TLO P1,PHONLY ;PHYSICAL ONLY FOR CORBND
>
CAMGE T3,VIRTAL ;IS THERE ENOUGH FREE VIRTUAL CORE IN SYSTEM?
>
IFE FT2REL,<
CAML T1,CORMAX ; YES, IS REQUEST LESS THAN MAX. ALLOWED COR+1?
>
IFN FT2REL,<
EXTERN SUMSEG
PUSHJ P,SUMSEG ;YES, IS SUM OF SEGS LESS THAN MAX. ALLOWED CORE+1?
>
POPJ P, ;NO, ERROR RETURN
IFN FTSWAP,<
AOJE T3,CPOPJ1 ;YES, GET NO. K OF INCREASE AND
;RETURN WITHOUT MOVING CORE IF NO CHANGE IN SIZE
IFN FTVM,<
CAILE J,JOBMAX ;IF A LOW SEG...
JRST CORE11
SKIPN R ;IF GOING FROM 0 TO N,
ADDI T3,UPMPSZ## ;U DECREASE VIRTAL
SKIPN T1 ;IF GOING FROM N TO 0,
SUBI T3,UPMPSZ## ;U DECREASE VIRTAL
CORE11: > ;END FTVM
MOVNS T3 ;MAKE MINUS FOR UPDATE
ADDM T3,VIRTAL ;AND UPDATE TOTAL VIRTUAL CORE IN SYSTEM
; SINCE THIS REQUEST CAN BE SATISFIIED
>
JRST CORE1A## ;GO ASSIGN CORE IN CORE OR ON THE DISK
;ROUTINE TO CLEAR PART OF JOB DATA AREA(PART PROTECTED FROM USER IO)
;CALLED WHEN SWAP READ ERROR AND AT SYSTEM RESTART(140)
; MOVE J,JOB NO.
;CALL: MOVE R,ADDRESS OF JOB DATA AREA
; PUSHJ P,CLRJOB
INTERNAL CLRJOB
EXTERNAL JOBPRT,JOBPR1,JOBPFI,JOBENB
EXTERNAL JOBPD1,JOBDDT
CLRJOB:
IFN FTKI10!FTKL10,<
PUSHJ P,SVEUB## ;MAKE SURE JOB DATA AREA IS ADDRESSABLE
>
SETZM JOBPRT(R) ;FIRST LOC. PROTECTED FROM USER
MOVSI T1,JOBPRT(R)
HRRI T1,JOBPR1(R)
MOVE T2,JOBDDT(R) ;SAVE DDT STARTING ADDRESS
BLT T1,JOBJDA##+17(R)
MOVEM T2,JOBDDT(R)
SETZM JOBENB(R) ;ALSO CLEAR APR ENABLE WORD
SETZM JOBPD1(R) ;AND UUO PC FLAGS(USED WHEN JOB STARTS)
PJRST ESTOP1 ;GO SET JOB STATUS NOT BE ALLOWED
;NOTE JACCT IS CLEARED
IFE FTVM,<
;SUBROUTINE TO RETURN EXTENDED EXEC PUSH DOWN LIST FOR CURRENT JOB
;(JOB HAS USER CORE TOO)
;AND MOVE PUSH DOWN LIST CONTENTS BACK TO USER AREA
;RESET PUSH DOWN POINTER BACK TO ORIGINAL LIST IN USER AREA
;CALL: SKIPE T2,USREPL
; PUSHJ P,GIVEPL
; ALWAYS RETURN
INTERN GIVEPL
EXTERN EPL4WD,USREPL
EXTERN JOBPD1,JOBLPD,MMXPDL,SYSSIZ
GIVEPL: HRRZ T1,P ;PUSH DOWN POINTER
CAML T1,LOCORE## ;P=NULPDL?
CAMLE T1,SYSSIZ ;IS IT STILL IN THE MONITOR (IN AN EPL)?
JRST GIVEP1 ;NO, DO NOT ADJUST P SINCE IT IS ALREADY IN USER AREA
HRLI T1,1(T2) ;(SOURCE)=BEG OF EXTENDED PD LIST+1
HRRI T1,JOBPD1+1(R) ;(DEST)=BEG OF USER PD LIST+1
BLT T1,JOBLPD(R) ;(STOP)=LAST T3 OF USER PD LIST
SUBI P,(T2) ;YES, BEG OF EPL-OLD CURRENT T3=CUR LENGTH
HRLI P,MMXPDL+1(P) ;CUR LENGTH-MAX LENGTH=-NO WORDS LEFT BEFORE PDOVF
ADDI P,JOBPD1(R) ;CUR LENGTH +BEG OF LIST IN USER AREA=NEW CURRENT T3
SKIPLE P ;DID IT FIT BACK IN THE JOB DATA AREA?
STOPCD GIVEP1,JOB,CRP, ;++CAN'T RETURN PDL
GIVEP1: SETZM USREPL ;FLAG NO MORE EXEC CORE ALLOCATED
MOVEI T1,EPL4WD ;SIZE OF EXTENDED PD LIST IN 4 WORDS
PJRST GIV4WD ;GIVE SPACE BACK AND RETURN
> ;END IFE FTVM
INTERN GET4WD,GIV4WD,GETWDS,GIVWDS,SETZRS
EXTERN SAVE4,FREPTR,LOCORE
;SUBROUTINE TO GET "FREE" CORE
;ENTER GET4WD: T2=# 4 WORD BLOCKS TO GET
;ENTER GETWDS: T2=# WORDS TO GET
;RETURN CPOPJ IF NOT AVAILABLE, WITH T2=LARGEST HOLE AVAILABLE
;RETURN CPOPJ1 IF GOTTEN, WITH T1=LOC OF CORE
GETWDS: ADDI T2,3 ;CONVERT TO 4 WORD BLOCKS
ASH T2,-2
GET4WD: MOVE T1,T2 ;NUMBER OF BLOCKSTO GET
MOVEI T2,FREPTR ;L(AOBJN WORD)
PUSH P,T1 ;SAVE NUMBER BEING REQUESTED
PUSHJ P,GETBIT ;GET, SET THE BITS
JRST GET4W2 ;NOT ENOUGH AVAILABLE
GET4W1: POP P,T2 ;RESTORE AMOUNT GOTTEN
IFN FTRSP,<
ADDM T2,FRUSED## ;BUMP FREE-CORE-USED WORD
>
LSH T1,2 ;*4 TO CONVERT TO AN ADDRESS
ADD T1,LOCORE ;+START OF TABLE = ACTUAL ADDRESS
PJRST CPOPJ1 ;TAKE GOOD RETURN
;HERE IF REQUESTED AMOUNT ISNT AVAILABLE
GET4W2: MOVE T2,T1 ;LARGEST HOLE WE FOUND
JRST TPOPJ## ;TAKE LOST RETURN
;SUBROUTINE TO ZERO BITS IN A BIT TABLE
;CALLING SEQUENCE:
; MOVE T1,NUMBER OF BITS TO CLEAR
; MOVE T2,AOBJN POINTER TO TABLE
; MOVE T3,BIT POSITION WITHIN TABLE
; PUSHJ P,ZERBTS
;ALWAYS RETURNS CPOPJ
ZERBTS::IDIVI T3,^D36 ;36 BITS/WORD
HRLS T3 ;WORD NUMBER TO BOTH HALVES
ADD T2,T3 ;POINT AOBJN POINTER TO WORD IN TABLE
MOVE T3,T4 ;BIT POSITION WITHIN WORD
PJRST SETZRS ;ZERO TIME BITS
;SUBROUTINE TO RETURN "FREE" CORE
;ENTER GIVWDS: T1=# WDS. TO RETURN, T2=START ADR. OF CORE
;ENTER GIV4WD: T1=# 4 WRD. BLOCKS TO RETURN, T2=START ADR. OF CORE
GIVWDS: ADDI T1,3 ;CONVERT TO # 4WD. BLOCKS
ASH T1,-2
GIV4WD: SUB T2,LOCORE ;GET ADR. RELATIVE TO START OF TABLE
IFN FTRSP,<
MOVN T3,T1
ADDM T3,FRUSED## ;DECREMENT FREE-CORE USED
>
LSH T2,-2 ;/4 TO CONVERT TO BITS
IDIVI T2,^D36 ;COMPUTE WORD LOC, STARTING BIT
HRLS T2 ;WORD POSITION IN BOTH HALVES
ADD T2,FREPTR ;SET AOBJN WORD FOR TABLE
;FALL INTO SETZRS
;SUBROUTINE TO SET ZEROS IN A TABLE
;ARG T1=HOW MANY BITS TO CLEAR
; T2=AOBJN POINTER FOR TABLE
; T3=POSITION IN WORD OF FIRST BIT TO CLEAR
; (0=BIT 0, 1=BIT 1, ETC.)
INTERN SETZRS
SETZRS: EXCH T1,T3 ;SET ACS FOR CLRBTS
MOVEI T4,^D36 ;ADJUST FOR 1ST WORD
SUBM T4,T1
HRRZ T4,T2 ;SET T4 FOR CLRBTS
PUSH P,T2 ;SAVE AOBJN WORD
PUSHJ P,CLRBTS ;CLEAR SOME BITS
STOPCD T2POPJ##,DEBUG,BAC, ;++BIT ALREADY CLEAR
POP P,T2 ;RESTORE AOBJN WORD
HLRE T3,T2 ;LENGTH OF POINTER
SUB T2,T3 ;COMPUTE TOP OF TABLE
CAILE T4,(T2) ;FINAL ADR PAST TOP?
STOPCD CPOPJ,DEBUG,PTT, ;++PAST TOP OF TABLE
POPJ P, ;NO, GOOD RETURN
INTERN GETZ,GETZR,SETOS
STRTAD==200000
;SUBROUTINE TO FIND N CONSECUTIVE 0'S IN A TABLE
;ENTER WITH P1 = AOBJN WORD TO THE TABLE
;P2 = PREVIOUS BEST SO FAR
;RH(P3)= HOW MANY, BIT STRTAD =1 IF START LOC SPECIFIED
;LH(P3) HAS BITS 0,1,2 USED BY FILSER
;EXIT CPOPJ1 IF FOUND, WITH P4 = WHERE THE HOLE IS, P1=UPDATED POINTER
;EXIT CPOPJ IF UNSUCCESSFUL, P2 = LARGEST HOLE FOUND
;P2,P4 CHANGED
;NOTE--SHOULD NOT CONTAIN A METER POINT SINCE IS CALLED
; BY ENDSTS ON 407 START BEFORE METINI IS CALLED
GETZ: TLNE P3,STRTAD ;START LOC SPECIFIED? (NOTE THAT ENTRY TO ROUTINE
; IS AT GETZR IF START LOC SPECIFIED)
POPJ P, ;YES, ERROR RETURN
MOVEI T4,^D36 ;NO. SET UP COUNT
SETCM T1,(P1) ;WORD TO INVESTIGATE
JUMPE T1,GETZ4 ;FULL IF 0
JUMPG T1,GETZ3 ;1ST BIT UNAVAILABLE IF POSITIVE
GETZ1: SETCA T1, ;SET TO REAL CONTENTS
JFFO T1,.+2 ;COUNT THE NUMBER OF 0'S
MOVEI T2,^D36 ;36 OF THEM
GETZR: MOVE T3,T2 ;SHIFT COUNT (T3 CAN BE .GT. 36 AT GETZ2)
MOVEM P1,P4 ;SAVE POSITION IN P4
HRLM T4,P4 ;LOC OF HOLE
GETZ2: CAIL T3,(P3) ;FOUND ENOUGH?
JRST CPOPJ1 ;YES. GOOD RETURN
CAILE T3,(P2) ;NO. BEST SO FAR?
HRRI P2,(T3) ;YES. SAVE IT
SUBI T4,(T2) ;DECREASE POSITION COUNTER
JUMPLE T4,GETZ5 ;0'S ON END
TLNE P3,STRTAD ;THIS HOLE NOT GOOD ENOUGH
POPJ P, ;ERROR RETURN IF START ADDRESS GIVEN
SETCA T1, ;NOW WE WANT TO COUNT 1'S
LSH T1,1(T2) ;REMOVE BITS WE ALREADY LOOKED AT
JUMPE T1,GETZ4 ;GO IF THE REST OF THE WORD IS ALL ONES
GETZ3: JFFO T1,.+1 ;NUMBER OF (REAL) 1'S
LSH T1,(T2) ;GET RID OF THEM
CAIN T4,^D36 ;1ST POSITION IN WORD?
ADDI T4,1 ;YES, SUBTRACT REAL JFFO COUNT
SUBI T4,1(T2) ;DECREASE POSITION COUNT
JUMPG T4,GETZ1 ;TRY NEXT 0 - HOLE
GETZ4: AOBJN P1,GETZ ;1'S ON END - START FRESH AT NEXT WORD
;HERE IF THE DESIRED SIZE NOT YET FOUND, BUT THE WORD HAD 0'S ON THE END
GETZ5: AOBJP P1,CPOPJ ;THROUGH IF END OF SAT
SKIPGE T1,(P1) ;NEXT WORD POSITIVE?
JRST GETZ ;NO. THIS HOLE NOT GOOD ENOUGH
JFFO T1,.+2 ;YES. COUNT THE 0'S
MOVEI T2,^D36 ;36 0'S
ADDI T3,(T2) ;ADD TO PREVIOUS ZERO-COUNT
MOVEI T4,^D36 ;RESET T4
JRST GETZ2 ;AND TEST THIS HOLE
;SUBROUTINE TO SET UP A BIT MASK FOR IORM OR ANDCAM INTO A TABLE
;ENTER WITH T1=POSITION (36=BIT0, 1=BIT35)
; AND T3=HOW MANY
;AFTER THE FIRST CALL USE BITMS2, T3=COUNT RETURNS T1=MASK,
;T3=REMAINING COUNT ROUTINE HAS RETURNED FINAL MASK IF
;T3 .LE. 0 ASSUMES T4=ADR IN TABLE, BITMS2 INCREMENTS T4
INTERN BITMSK,BITMS2
BITMSK: PUSH P,T1 ;SAVE POSITION
MOVN T1,T3 ;- COUNT
CAILE T3,^D36 ;MORE THAN 1 WORD?
MOVNI T1,^D36 ;YES, SETTLE FOR A WORD (OR LESS)
MOVSI T2,400000 ;SET TO PROPOGATE A MASK
ASH T2,1(T1) ;GET THE RIGHT NUMBER OF BITS
SETZ T1,
LSHC T1,@0(P) ;POSITION THE BITS IN T1 (=MASK)
SUB T3,0(P) ;REDUCE THE COUNT TO THE NEW VALUE
PJRST T2POPJ## ;AND RETURN
;HERE AFTER FIRST CALL, MASK STARTS AT BIT 0
BITMS2: SETO T1, ;MASK STARTS AT BIT 0
MOVNI T2,-^D36(T3) ;SET UP SHIFT
CAIGE T3,^D36 ;DONT SHIFT IS .GE. 36
LSH T1,(T2) ;POSTION THE MASK
SUBI T3,^D36 ;REDUCE THE COUNT
AOJA T4,CPOPJ ;UPDATE THE POSITION AND RETURN
;SUBROUTINE TO MARK BITS AS TAKEN IN A TABLE
;USES ACS AS RETURNED BY GETZ - P3=HOW MANY
; LH(P4)=POSITION, RH(P4)=WHERE (POSITION=36 IF BIT0, 1 IF BIT35)
;RETURNS CPOPJ IF BIT IS ALREADY SET, CPOPJ1 NORMALLY RESPECTS T1
SETOS: PUSH P,T1 ;SAVE T1
MOVE T4,P4 ;WHERE
HRRZ T3,P3 ;COUNT
HLRZ T1,P4 ;POSITION IN WORD
PUSHJ P,BITMSK ;SET UP A MASK
SETOS1: CONO PI,PIOFF## ;BETTER NOT INTERRUPT HERE
TDNE T1,(T4) ;BIT ALREADY ON?
JRST SETOS2 ;YES
IORM T1,(T4) ;NO, NOW IT IS
CONO PI,PION## ;RESTOR PI
JUMPLE T3,TPOPJ1## ;DONE IF COUNT .LE. 0
PUSHJ P,BITMS2 ;NOT DONE, GET MASK FOR NEXT WORD
JRST SETOS1 ;AND GO SET THE BITS IN THAT WORD
;HERE IF BIT ALREADY ON
SETOS2: CONO PI,PION## ;PI CAN BE ON
PUSH P,T3 ;SAVE CURRENT COUNT
HLRZ T1,P4 ;RESTORE ORIGINAL VALUES
HRRZ T3,P3
MOVE T4,P4
PUSHJ P,BITMSK ;AND GENERATE A MASK
SETOS3: CAMN T3,(P) ;IS THE COUNT FOR MASK=COUNT WHEN SET?
JRST SETOS4 ;YES, DONE
ANDCAM T1,(T4) ;NO, CLEAR THOSE BITS
PUSHJ P,BITMS2 ;GENERATE NEXT MASK
JRST SETOS3 ;AND CONTINUE
SETOS4: POP P,(P) ;CLEARED ALL THE RIGHT BITS - FIX PD LIST
PJRST TPOPJ## ;AND NON-SKIP RETURN
;SUBROUTINE TO OBTAIN FREE BITS, MARK THEM AS TAKEN IN THE TABLE
;ENTER WITH T1=HOW MANY,
;T2=XWD ADR OF 1ST WORD OF TABLE, ADR OF TABLE AOBJN WORD (OR 0, LOC OF AOBJN)
;RETURNS CPOPJ IF NOT ENOUGH AVAILABLE, T1=SIZE OF LARGEST HOLE
;RETURNS CPOPJ1 IF GOTTEN, T1= RELATIVE ADDRESS OF BLOCK OBTAINED
;T3 IS UPDATED AOBJN POINTER
INTERN GETBIT
GETBIT: PUSHJ P,SAVE4 ;SAVE P1-P4
TLNN T2,-1 ;STARTING AT AN OFFSET?
HRL T2,(T2) ;NO, START AT FIRST WORD
PUSH P,T2 ;SAVE ADR OF AOBJN WORD FOR TABLE
GETBI1: MOVE P1,0(P) ;GET AOBJN WORD
MOVE P1,(P1)
SETZ P2, ;NO BEST SO FAR
MOVE P3,T1 ;NUMBER OF BITS TO GET
PUSHJ P,GETZ ;GET THE BITS
JRST GETBI2 ;NOT ENOUGH AVAILABLE
HRRZ T1,P4 ;GOT THEM - FIRST WORD WITH ZEROES
HLRZ T2,(P) ;LOC OF FIRST WORD OF TABLE
SUBI T1,(T2) ;COMPUTE RELATIVE ADDRESS OF START
IMULI T1,^D36 ;36 BITS PER WORD
HLRZ T2,P4 ;BIT POSITION OF 1ST 0 IN THE WORD
MOVNS T2
ADDI T1,^D36(T2) ;T1= RELATIVE LOC WITHIN THE TABLE
PUSHJ P,SETOS ;MARK THE BITS AS TAKEN
SKIPA T1,P3 ;SOME FINK SNUCK IN ON US!
AOSA -1(P) ;GOT THEM - WIN RETURN
JRST GETBI1 ;TRY AGAIN TO GET SOME BITS
MOVE T3,P1 ;UPDATED POINTER
JRST T2POPJ## ;RETURN
;HERE IF NOT ENOUGH ARE AVAILABLE
GETBI2: MOVE T1,P2 ;T1=LARGEST HOLE FOUND
PJRST T2POPJ## ;NON-SKIP RETURN
;ROUTINE TO CLEAR BITS FROM A TABLE
;ENTER T1=POSITION, T3=COUNT, T4=TABLE ADR
; POSITION=36 IF BIT0, 1 IF BIT35
;RETURNS POPJ IF BIT ALREADY 0, POPJ1 OTHERWISE
INTERN CLRBTS
CLRBTS: PUSHJ P,BITMSK ;GENERATE A MASK
CLRBT1: CONO PI,PIOFF## ;CANT INTERRUPT
MOVE T2,(T4) ;WORD TO CLEAR BITS FROM
TDC T2,T1 ;ARE THE BITS ALREADY OFF?
TDNE T2,T1
PJRST ONPOPJ## ;YES, RESTORE PI AND NON-SKIP
MOVEM T2,(T4) ;NO, NOW THEY ARE
CONO PI,PION## ;RESTORE THE PI
JUMPLE T3,CPOPJ1 ;DONE IF COUNT .LE. 0
PUSHJ P,BITMS2 ;GENERATE MASK FOR NEXT WORD
JRST CLRBT1 ;AND GO CLEAR THOSE BITS
;SUBROUTINE TO FIND N CONSECUTIVE ZEROS IN A TABLE
;ARGS T1=AOBJN POINTER TO TABLE
; T2=PREVIOUS BEST
; T3=HOW MANY, BIT STRTAD=1 IF START ADDR SPECIFIED
;VALUES IF UNSUCCESSFUL, T2=LARGEST HOLE FOUND, NON-SKIP RETURN
; IF SUCCESSFUL, T4=POSITION OF BEGINNING OF HOLE, SKIP RETURN
;THIS ROUTINE CALLS GETZ BUT SATISFIES STANDARD AC CONVENTIONS
INTERN CLGETZ
CLGETZ: PUSHJ P,SAVE4 ;SAVE GLOBAL ACS
MOVE P1,T1 ;SET ACS FOR GETZ
MOVE P2,T2
MOVE P3,T3
PUSHJ P,GETZ ;GET THE BITS
CAIA ;NOT ENOUGH AVAILABLE
AOS (P) ;OK, SET FOR SKIP RETURN
MOVE T1,P1 ;RESTORE T-ACS WITH ANSWERS
MOVE T2,P2
MOVE T3,P3
MOVE T4,P4
POPJ P, ;TAKE WIN OR LOSE RETURN
;SUBROUTINE TO SET BITS IN A TABLE
;ARGS T3=HOW MANY
; T4=POSITION OF FIRST, RH=ADDR, LH=POSITION, 36=BIT 0,1=BIT 35
;THIS ROUTINE CALLS SETOS BUT SATISFIES STANDARD AC CONVENTIONS
CSETOS::PUSHJ P,SAVE4 ;SAVE P1-P4
MOVE P3,T3 ;SET ACS FOR SETOS
MOVE P4,T4
PUSHJ P,SETOS ;SET THE BITS
STOPCD CPOPJ,DEBUG,BNZ, ;++BIT NOT ZERO
POPJ P, ;OK, RETURN
COREND: END