.TITLE PARSIZ - CHANGE THE SIZE OF GEN. .IDENT /V2203C/ .SBTTL PARSIZ - TITLE PAGE. .ENABL LC ;+ ; ; AUTHOR: RODGER S. MILES 21-MAR-80 ; ; UPDATE: RSM001 25-MAR-80 ; ADD SWITCH STACK (DISABLE TASK SWITCHING) AND ; CHECK TO MAKE SURE NO SUBPARTITION EXISTS IN ; THE AREA TO BE DELETED. ; UPDATE: RSM002 14-APR-80 ; ADD SUBROUTINE TO PARSE THE COMMAND LINE AND ; USE THE VALUES $PSIZE AND $PARNM. ; ; THIS TASK WILL MODIFY THE SIZE OF A MAIN PARTITION. ; A COMMAND LINE MAY OPTIONALLY BE PASSED WHICH WILL ; CONTAIN THE PARTITION NAME "/PAR=PNAME", OR THE END ; OF THE PARTITION "/SIZE=PSIZE". UNLESS SPECIFIED, ; IT WILL DEFAULT TO CHANGE THE GEN PARTITION TO FIT IN ; 96K-WORDS. DESIGNED TO RUN ON A QUESCIENT SYSTEM ; BEFORE BRINGING UP AN OPERATIONAL SYSTEM, THE TASK ; WILL CHECK FOR POSSIBLE MEMORY CONFLICTS. IF ANY ARE ; DISCOVERED, THE TASK WILL ISSUE A SHORT MESSAGE AND ; EXIT WITHOUT UPDATING THE PARTITION CONTROL BLOCK (PCB). ; TASK SWITCHING IS DISABLED, TO INSURE THAT NO OTHER ; USERS WILL BE WORKING WHEN THE PCB IS UPDATED. ; THE TASK IS PRIVILEDGED AND MUST BE BUILT WITH THE ; FOLLOWING: ; ; TKB>PARSIZ/PR/-CP,PARSIZ/CR/-SP=PARSIZ,PSZPRS ; TKB>LB:[1,54]RSX11M.STB/SS ; TKB>/ ; ENTER OPTIONS: ; TKB>STACK=10 ; TKB>UNITS=1 ; TKB>ASG=TI:1 ; TKB>TASK=...PSZ ; TKB>// ; ;- .SBTTL ...... - MACRO AND CONSTANT DEFINITIONS .MCALL QIOW$ ,EXIT$S,DIR$ ,PCBDF$ .MCALL GMCR$ PCBDF$ ;DEFINE THE PARTITION CONTROL BLOCK. TILUN = 1 ;TERMINAL LOGICAL UNIT NUMBER. TIEFN = 1 ;EVENT FLAG NUMBER FOR I/O U2.PRV = 10 ;PRIVILEGED TERMINAL BIT OF ;DEVICE CHARACTERISTIC WORD 2. ;NORMALLY DEFINED IN UCBDF$ MACRO ;OF [1,1]EXEMC.MLB. .SBTTL PARSIZ - MAIN LINE. .PSECT CODE,I .ENABL LSB PARSIZ:: ; ; GET MCR COMMAND LINE AND CHECK FOR TERMINAL PRIVILEGES. ; DIR$ #$GTMCR ;GET MCR COMMAND LINE BCS 4$ ;IF CS COMMAND I/O ERROR, ; JUST USE THE DEFAULTS. MOV $TKTCB,R4 ;GET ADDRESS OF TASK TCB MOV T.UCB(R4),R4 ;GET ADDRESS OF TI UCB BIT #U2.PRV,U.CW2(R4) ;IS TERMINAL PRIVILEGED? BNE 1$ JMP 97$ 1$: MOV #$GTMCR+G.MCRB,R0 ;GET ADDRESS OF MCR COMMAND LINE MOV @#$DSW,R1 ;GET MCR LINE BYTE COUNT ADD R0,R1 ;POINT TO END OF LINE CLRB (R1) ;USE NULL CHARACTER FOR END-OF-LINE CALL PSZPRS ;PARSE THE COMMAND LINE. BCC 2$ JMP 95$ 2$: TST $PARNM ;WAS A PARTITION NAME GIVEN? BNE 5$ ;YES - LET IT BE. 4$: MOV #GENNM,$PARNM ;NO - USE THE DEFAULT NAME. 5$: MOV $PSIZE,-(SP) ;size entered? BIS $TOP,(SP) ;or top? BIS $BOT,(SP)+ ;or bottom? BNE 10$ ;if any, skip MOV #LIMIT,$PSIZE ;NO - USE THE DEFAULT VALUE. 10$: CALL $SWSTK,PRNT ;DISABLE TASK SWITCHING, BY GOING ;TO SYSTEM LEVEL. TST $SQZ ;find space? BEQ 15$ ;if not, skip MOV @$PARHD,R0 ;first partition CLR R5 ;assume no candidate for predecessor MOV #177777,R3 ;any space found is less than this 1900$: MOV R0,R2 ;remember candidate CMP P.NAM(0),$COM ;must do name check BNE 1905$ CMP P.NAM+2(0),$COM+2 BNE 1905$ MOV #DUPCOM,MSG ;duplicate common RETURN 1905$: MOV P.REL(0),R1 ;start ADD P.SIZE(0),R1 ;+size = top MOV (0),R0 ;next partition BEQ 1910$ ;skip if no more MOV P.REL(0),R4 ;its start BR 1915$ 1910$: MOV $SYSIZE,R4 ;top of memory 1915$: SUB R1,R4 ;available space BCS 1925$ CMP $SQZ,R4 ;enough? BHI 1920$ ;if not, skip CMP R4,R3 ;under previous space? BHIS 1920$ ;if not, skip MOV R4,R3 ;current smallest fit MOV R2,R5 ;save predecessor 1920$: TST R0 ;more partitions? BNE 1900$ ;if yes, loop 1925$: TST R5 ;any predecessor? BEQ 1930$ ;if not, skip MOV R3,-(SP) ;smallest fit SUB $SQZ,(SP) ;leftover space in hole MOV P.REL(5),R3 ADD P.SIZE(5),R3 ;top of chosen predecessor ADD (SP)+,R3 ;bottom of new partition JMP 135$ ;to common setup 1930$: ;must try to clip GEN 15$: MOV #$PARHD,R0 ;GET THE MAIN PCB LISTHEAD. 20$: MOV R0,R2 ;R2 holds last PCB MOV @R0,R0 ;POINT TO THE NEXT PCB. BNE 2000$ JMP 93$ ;NO SUCH PARTITION 2000$: CMP P.NAM(R0),$PARNM ;DOES 1ST HALF OF NAME MATCH? BNE 20$ ;NO - GO TO NEXT ONE. CMP P.NAM+2(R0),$PARNM+2 ;DOES 2ND HALF MATCH? BNE 20$ ;NO - TRY AGAIN. BIT #PS.DRV,P.STAT(0) ;driver installed? BEQ 2005$ JMP 83$ ;cant change driver partition 2005$: TST $NOC ;removal of common? BEQ 2030$ ;if not, skip BITB #PS.COM,P.STAT(0) ;is it a common? BNE 2010$ ;if yes, skip MOV #NOTCOM,MSG ;not a common RETURN 2010$: TST P.ATT(0) ;tasks installed? BEQ 2015$ ;if not, skip MOV #BADTSK,MSG ;error RETURN 2015$: ;ok to remove common MOV (0),(2) ;close up thread MOV #P.LGTH,R1 CALL $DEACB ;deallocate pool CLR $PARNM+2 ;we repeat with GEN CLR $NOC MOV #GENNM,$PARNM ;now operate on GEN BR 15$ ;back to start 2030$: MOV P.REL(0),R3 ;partition start TST $SQZ ;find space? BEQ 2050$ ;if not, skip MOV (0),R2 ;next BNE 2035$ MOV $SYSIZE,R1 ;top of memory BR 2040$ 2035$: MOV P.REL(2),R1 ;bottom of next partition 2040$: SUB $SQZ,R1 ;deisired top of GEN BR 30$ ;to new top operation 2050$: TST $BOT ;bottom specified? BEQ 24$ ;if not, skip MOV $BOT,R3 ;new bottom TST $BTINC ;increment/decrement? BEQ 21$ ADD P.REL(0),R3 ;new bottom 21$: MOV $EXSIZ,R4 ;exec. size ADD #77,R4 CLC ROR R4 ;divide by 64 ASR R4 ASR R4 ASR R4 ASR R4 ASR R4 MOV R4,-(SP) ;lower limit (if first partition munged) CMP #$PARHD,R2 ;first? BEQ 22$ ;if yes, skip MOV P.REL(2),(SP) ;start of next lower partition ADD P.SIZE(2),(SP) CMP (SP),R4 ;exec. top is a lower limit BHIS 22$ MOV R4,(SP) 22$: CMP (SP)+,R3 ;above lower partition? BHI 84$ ;if not, skip MOV P.REL(0),R4 ADD P.SIZE(0),R4 ;will stay as top (if no change) 24$: MOV $PSIZE,R1 ;see if size speced BNE 26$ ;if yes, skip MOV $TOP,R1 ;new top BNE 25$ MOV R4,R1 ;use old top BR 30$ 25$: TST $AST ;as big as possible? BEQ 28$ ;if not, skip MOV (0),R2 ;next partition BNE 27$ ;skip if one exists MOV $SYSIZE,R1 ;use top of memory BR 30$ 27$: MOV P.REL(2),R1 ;bottom of next is top of this BR 30$ 28$: TST $INC ;can be +, -, or absolute BEQ 30$ ;0=> absolute value ADD P.SIZE(0),R1 ;new size BLE 85$ TST $BTINC BEQ 26$ SUB $BOT,R1 ;allows BOT=+1/TOP=+1 to preserve size BLE 85$ 26$: ADD R3,R1 ;new top 30$: MOV R1,R4 ;save top SUB R3,R1 ;YES - GET THE NEW PARTITION SIZE. BLOS 90$ ;OUCH! PARTITION STARTS ABOVE LIMIT. CMP $SYSIZE,R4 ;abovephysical memory? BLO 87$ MOV (0),R2 ;on increase we check against next... BEQ 35$ ;...but if no more, against memory top CMP P.REL(2),R4 ;below next? BLO 86$ ;if not, error 35$: ; ; WE HAVE FOUND THE GEN PARTITION IS GOOD SHAPE, NOW ; LET'S CHECK THE SUBPARTITIONS. ; R3 = new bottom ; R4 = new top ; R1 = new size ; MOV P.SUB(R0),R2 ;POINT TO THE FIRST SUBPARTITION. BEQ 60$ ;FINISH UP, THERE ARE NO SUBS. 45$: TST P.STAT(R2) ;IS THIS SUBPART. IS IN CORE? BMI 50$ ;NO - JUST GO TO THE NEXT. CMP P.REL(2),R3 ;sub below new bottom? BLO 82$ ;if yes, skip MOV P.REL(R2),-(SP) ;YES - GET ITS BASE, AND ADD P.SIZE(R2),(SP) ; COMPUTE ITS TOP. CMP (SP)+,R4 ;IS IT OVER THE NEW LIMIT? BHI 80$ ;YES - REPORT AND GET OUT. ;NO - THIS ONE IS GOOD. 50$: MOV P.SUB(R2),R2 ;GET THE NEXT PCB. BNE 45$ ;NOT AT END, CHECK NEXT PCB. 60$: MOV $TSKHD,R2 ;search installed task thread 70$: TST T.TCBL(2) ;null task? BEQ 100$ ;if yes, done MOV T.PCB(2),R4 ;task PCB CMP R4,R0 ;in this task partition? BNE 72$ ;if not, skip BIT #PS.SYS,P.STAT(0) ;system partition? BEQ 88$ ;if not, problem 71$: CMP T.MXSZ(2),R1 ;task too big? BHI 94$ ;if yes, skip 72$: MOV T.TCBL(2),R2 ;next task BR 70$ ;loop 80$: MOV #BADSUB,MSG ;TELL USER THAT SUBPARTITION EXIST RETURN ;IN THE AREA TO BE FREED. 81$: MOV #BADCOM,MSG ;common installed RETURN 82$: MOV #BADSB2,MSG RETURN 83$: MOV #BADDRV,MSG ;driver installed RETURN 84$: MOV #BDLWP,MSG ;bad lower partition RETURN 85$: MOV #TOOLOW,MSG ;TELL USER THAT PARTITION IS ALREADY RETURN ;BELOW THE LIMIT. 86$: MOV #INUSE,MSG ;memory in use RETURN 87$: MOV #NOMEM,MSG ;no such memory RETURN 88$: MOV #BADTSK,MSG ;tasks installed in TASK partition RETURN 90$: MOV #TOOHI,MSG ;TELL USER THAT PARTITION IS ABOVE RETURN ;THE LIMIT. 93$: MOV #NOPAR,MSG ;TELL USER PARTITION ISN'T HERE. RETURN ; 94$: MOV #TOOBIG,MSG ;task is too big RETURN 95$: MOV #SYNTAX,MSG ;INDICATE A SYNTAX ERROR. BR PRNT ; 97$: MOV #NOTPRV,MSG ;INDICATE THE USER WASN'T ALLOWED. ;fall into print PRNT: TST MSG ;any message? BEQ DONE MOV @MSG,QIO+Q.IOPL ;GET THE MESSAGE ADDRESS. ADD #2,MSG ;POINT TO THE SIZE. MOV @MSG,QIO+Q.IOPL+2 ;AND GET THE SIZE. DIR$ #QIO ;ISSUE A MESSAGE TO THE USER DONE: EXIT$S ;AND EXIT (COULD DUMP PCB HERE.) 100$: ;can change size MOV R1,P.SIZE(0) ;new size MOV R3,P.REL(0) ;new bottom CLR MSG ;no msg. required TST $COM ;common specified? BEQ 150$ ;if not, skip MOV $PARHD,R4 110$: BEQ 130$ ;skip if no more CMP P.NAM(4),$COM ;same name? BNE 120$ CMP P.NAM+2(4),$COM+2 BNE 120$ 115$: MOV #DUPCM,MSG ;duplicate common RETURN 120$: MOV (4),R4 ;next PCB BR 110$ 130$: MOV R0,R5 ;address of predecessor ADD R1,R3 ;bottom of new partition 135$: MOV #P.LGTH,R1 CALL $ALOCB ;allocate pool BCC 140$ MOV #NOPOL,MSG RETURN 140$: MOV (5),-(SP) ;link for changed partition MOV R0,(5) ;link it to here MOV (SP)+,(0)+ ;this links to its successor CLR (0)+ ;pri., ioc MOV $COM,(0)+ ;name MOV $COM+2,(0)+ CLR (0)+ ;no sub. MOV (5),(0)+ ;main MOV R3,(0)+ ;bottom MOV $TOP,(0) NEG (0)+ ;size MOV R0,R3 CLR (0)+ MOV R3,(0)+ ;wait thread MOV #200,(0)+ ;mark partition busy CLR (0)+ ;P.TCB MOV #PS.COM,(0)+ ;status .IF DF M$$MGE CLR (0)+ ;P.PRO .ENDC BIT #FE.PLA,$FMASK ;PLAS? BEQ 150$ CLR (0)+ ;P.PRO MOV R0,R3 CLR (0)+ ;P.ATT MOV R3,(0)+ 150$: RETURN ;done .SBTTL DATA - LOCAL DATA AREA. .PSECT DATA,D .NLIST BEX $GTMCR: GMCR$ ;DPB AND BUFFER FOR COMMAND LINE. MSG: .WORD 0 ;STORAGE FOR ADDRESS OF MESSAGE ;TO PASS BACK FROM SYSTEM STATE. ;PARAMETERS FOR QIOW DIRECTIVE: ; 1 - MESSAGE ADDRESS ; 2 - MESSAGE SIZE TOOLOW: .WORD MSGTL,MSGTLS TOOBIG: .WORD MSGBG,MSGBGL BADSUB: .WORD MSGBS,MSGBSS BDLWP: .WORD MSGLP,MSGLPL BADSB2: .WORD MSGBLS,MSGBLL BADCOM: .WORD MSGBCM,MSGBCL DUPCOM: .WORD DOPCM,DOPCML BADDRV: .WORD MSGBDR,MSGBDL BADTSK: .WORD MSGTSK,MSGTKL TOOHI: .WORD MSGTH,MSGTHS NOPAR: .WORD MSGNG,MSGNGS NOTCOM: .WORD NOTCM,NOTCML SYNTAX: .WORD MSGSE,MSGSES NOTPRV: .WORD MSGNP,MSGNPS INUSE: .WORD MSGIU,MSGIUS NOMEM: .WORD MSGNM,MSGNMS NOPOL: .WORD NOPLM,NOPLML DUPCM: .WORD DPCMM,DPCMML IOSB: .BLKW 2 ;I/O STATUS BLOCK (UNUSED) NOTCM: .ASCII /PSZ - Not a common partition/ NOTCML = . - NOTCM DOPCM: .ASCII /PSZ - Partition already exists/ DOPCML = . - DOPCM NOPLM: .ASCII /PSZ - Partition changed; but no pool for common/ NOPLML = . - NOPLM DPCMM: .ASCII /PSZ - Partition changed; but duplicate common name/ DPCMML = . - DPCMM MSGIU: .ASCII /PSZ - Desired memory is being used by next partition/ MSGIUS = .-MSGIU MSGLP: .ASCII /PSZ - Desired memory in use by previous partition/ MSGLPL = .-MSGLP MSGNM: .ASCII /PSZ - No extra memory supplied without a purchase order/ MSGNMS = .-MSGNM MSGBS: .ASCII /PSZ - Subparition would be above new top/ MSGBSS = .-MSGBS MSGBLS: .ASCII /PSZ - Subpartition would be below new bottom/ MSGBLL = .-MSGBLS MSGBCM: .ASCII /PSZ - Common installed (and attached) in partition/ MSGBCL = .-MSGBCM MSGBDR: .ASCII /PSZ - Driver installed in partition/ MSGBDL = .-MSGBDR MSGTSK: .ASCII /PSZ - Task (or common) partition with installed task/ MSGTKL = .-MSGTSK MSGBG: .ASCII /PSZ - Installed task is larger than desired size/ MSGBGL = .-MSGBG MSGTL: .ASCII /PSZ - Partition end is below limit/ MSGTLS = .-MSGTL MSGTH: .ASCII /PSZ - Partition located above limit/ MSGTHS = .-MSGTH MSGNG: .ASCII /PSZ - No such partition/ MSGNGS = .-MSGNG MSGNP: .ASCII /PSZ - User must be priviledged/ MSGNPS = .-MSGNP MSGSE: .ASCII /PSZ - Syntax error/ MSGSES = .-MSGSE .EVEN $PARNM:: ;PARTITION NAME .WORD 0,0 ; GENNM = ^RGEN ;DEFAULT IS 'GEN' $TOP:: .WORD 0 $SQZ:: .WORD 0 $INC:: .WORD 0 ;flags top as absolute or relative $BOT:: .WORD 0 $NOC:: .WORD 0 $AST:: .WORD 0 $BTINC::.WORD 0 $PSIZE:: ;END OF PARTITION. .WORD 0 ; $COM:: 0,0 ;common name LIMIT = 5000 ; DEFAULT TO 96KW. QIO:: ;QIO DIRECTIVE PARAM. BLOCK QIOW$ IO.WVB,TILUN,TIEFN,,IOSB,,<0,0,40> .LIST BEX .END PARSIZ