*DECK EXREDUC
PROC EXREDUC( (REDSIZE), TSBN, FIFO, TSBADDR );
BEGIN
*IF DEF,IMS
#
** EXREDUC - REDUCE TSB SIZE.
*
* M. E. VATCHER 81/03/16
*
* EXREDUC REMOVES EITHER THE UPPER OR LOWER ADDRESS PORTION OF
* AN ASSIGNED TSB.
*
* PROC EXREDUC((REDSIZE),TSBN,FIFO,TSBADDR)
*
* ENTRY REDSIZE NUMBER OF WORDS TO RELEASE
* TSBN TSB NUMBER OF TSB TO HAVE REDUCED SIZE
* FIFO BOOLEAN INDICATING UPPER OR LOWER PORTION
* OF TSB TO BE RELEASED
*
* EXIT TSBADDR FWA OF USER AREA OF NON-MOVABLE TSB
*
* METHOD
*
* IF SOMETHING IS WRONG WITH THE TSB NUMBER THEN SET TSBADDR = -1
* AND RETURN. IF THE NUMBER OF WORDS TO REMOVE IS GREATER THAN
* THE TSB LENGTH THEN SET TSBADDR TO -1 AND RETURN. OTHERWISE
* IF NOT FIFO THEN MAKE A FREE TSB WITH THE HIGHER ADDRESS
* PORTION OF THE TSB. IF FIFO THEN MAKE A FREE TSB WITH THE
* LOWER ADDRESS PORTION OF THE TSB.
*
#
*ENDIF
CONTROL NOLIST; # TSBDEFS, TSBDATA, TSBBASE, CYBERDEFS #
*CALL CYBERDEFS
*CALL TSBDEFS
*CALL TSBDATA
*CALL TSBBASE
CONTROL LIST;
XREF
BEGIN
PROC ABORT;
PROC GIVETSB;
END
ITEM FFWA U; # FWA OF NEW FREE TSB #
ITEM FIFO B; #INDICATES WHICH PORTION OF TSB TO RELEASE#
ITEM REDSIZE U; # NUMBER OF WORDS TO RELEASE #
ITEM TSBADDR U; # FWA OF USER AREA OF NON-MOVABLE TSB #
ITEM TSBN U; # TSB NUMBER OF TSB TO SHRINK #
ITEM TSBSIZE U; # SIZE OF SHRUNK TSB #
IF ( NOT TBUSY[TSBN] ) OR ( TSBN GR LENGTH[0] )
OR ( TSBN LQ 0 )
THEN # TSBN IS ILLEGAL #
BEGIN
$BEGIN
ABORT;
$END
TSBADDR = -1; # NEGATIVE ADDRESS INDICATES REJECT #
TSBN = BADTSBN; # BAD TSBN ERROR CODE #
RETURN; # ***** EXIT ***** #
END
P<BTSBHDR> = TTSBFWA[TSBN];
IF REDSIZE GQ BTSBL[0]
THEN # AMOUNT TO RELEASE EXCEEDS TSB LENGTH #
BEGIN
$BEGIN
ABORT;
$END
TSBADDR = -1; # NEGATIVE ADDRESS INDICATES REJECT #
TSBN = BADSIZE; # BAD TSB SIZE ERROR CODE #
RETURN; # ***** EXIT ***** #
END
TSBSIZE = BTSBL[0] - REDSIZE; # SHRUNK TSB SIZE #
IF NOT FIFO
THEN # RELEASE HIGH ADDRESS PORTION #
BEGIN
FFWA = TTSBFWA[TSBN] + TSBSIZE; # FWA OF NEW FREE TSB #
BNOTMOV[0] = TRUE; # SET NOT MOVABLE #
BTSBL[0] = TSBSIZE; # SET NEW BUSY TSB LENGTH #
P<FTSBHDR> = FFWA; # POINT TO AREA TO RELEASE #
FHDRRSV[0] = 0;
FPTSBL[0] = TSBSIZE;
FTSBL[0] = REDSIZE; # PREPARE FOR CALL TO GIVETSB #
P<BTSBHDR> = LOC(FTSBHDR) + REDSIZE; #POINT TO NEXT TSB #
BPTSBL[0] = REDSIZE; # SET PREVIOUS TSB SIZE #
GIVETSB(FFWA); # CONSOLIDATE FREE SPACE #
END
ELSE # RELEASE LOWER ADDRESS PORTION #
BEGIN
P<BTSBHDR> = TTSBFWA[TSBN] + REDSIZE; # FORMAT NEW BUSY HEADER #
BBUSY[0] = TRUE;
BNOTMOV[0] = TRUE; # SET NOT MOVABLE #
BIDENT[0] = TSBN; # SET TSB NUMBER #
BHDRRSV[0] = 0;
BTSBL[0] = TSBSIZE; # SET TSB SIZE #
BPTSBL[0] = REDSIZE; # SET PREVIOUS TSB SIZE #
P<FTSBHDR> = TTSBFWA[TSBN]; # POINT TO NEW FREE TSB #
TTSBFWA[TSBN] = TTSBFWA[TSBN] + REDSIZE;
FTSBL[0] = REDSIZE; # PREPARE FOR CALL TO GIVETSB #
FHDRRSV[0] = 0;
P<BTSBHDR> = LOC(BTSBHDR) + BTSBL[0]; # POINT TO NEXT TSB #
BPTSBL[0] = TSBSIZE; #SET PREVIOUS TSB LENGTH #
GIVETSB(LOC(FTSBHDR)); # CONSOLIDATE FREE SPACE IF POSSIBLE #
END
TSBADDR = TTSBFWA[TSBN] + TSBHDRL; # FWA OF USER AREA #
END TERM # EXREDUC #