ASMB,R
 HED * REAL-TIME EXECUTIVE  MEMORY ALLOCATION * 
*     NAME:   $ALC
*     SOURCE: 92067-18022 
*     RELOC:  PART OF 92067-16014 
*     PGMR:   G.A.A.
* 
*  ***************************************************************
*  * (C) COPYRIGHT HEWLETT-PACKARD COMPANY 1978.  ALL RIGHTS     *
*  * RESERVED.  NO PART OF THIS PROGRAM MAY BE PHOTOCOPIED,      *
*  * REPRODUCED OR TRANSLATED TO ANOTHER PROGRAM LANGUAGE WITHOUT*
*  * THE PRIOR WRITTEN CONSENT OF HEWLETT-PACKARD COMPANY.       *
*  ***************************************************************
* 
      NAM $ALC,0 92067-16014 REV.1805 741120
* 
      ENT $ALC,$RTN,$PNTR 
      EXT $LIST,$WORK 
* 
*     PROGRAMMER:  G.A. ANZINGER   HP AMD  1 MAY 70  BCS
*                                         24 JUN 74  RTE
* 
*     REQUESTS MAY BE MADE TO ALLOCATE AND RELEASE BUFFERS
*     FROM THE MEMORY AVAILABLE AFTER LOADING.
* 
*      1. ALLOCATE: CALLING SEQUENCE -
*         (P)     JSB $ALC
*         (P+1)   (# OF WORDS NEEDED) 
*         (P+2)   -RETURN NO MEMORY EVER (A)=-1, (B)=MAX EVER 
*         (P+3)   -RETURN NO MEMORY NOW  (A)=0,  (B)=MAX NOW
*         (P+4)   -RETURN OK    (A)=ADDR , (B)=SIZE OR SIZE+1 
* 
*      2. RELEASE BUFFER TO AVAILABLE MEMORY
*         (P)     JSB $RTN
*         (P+1)   (FWA OF BUFFER) 
*         (P+2)   (# OF WORDS RETURNED) 
*         (P+3)    -RETURN-  (ALL REGISTERS DESTROYED)
* 
*     IF A REQUEST FOR A BUFFER OF LENGTH X CANNOT BE FILLED
*     DURING A GIVEN CALL, RETURN IS MADE WITH: 
*         (A) = 0 
* 
*     IF, WHEN BUFFER REQUESTED, - (AVMEM) - SHOWS INSUFFICIENT CORE
*     AVAILABLE TO CONTAIN A BUFFER OF THE LENGTH REQUESTED,
*     THEN RETURN IS MADE WITH: 
*         (A) = -1
*         (B) = MAXIMUM LENGTH BUFFER THAT THE PROGRAM MAY ALLOCATE.
* 
*     TO FIND OUT HOW LARGE A BUFFER MAY BE ALLOCATED, USE THE CALL 
* 
*                   JSB $ALC
*                   DEC 32767 
* 
*     BLOCKS OF MEMORY AVAILABLE FOR OUTPUT BUFFERING ARE LINKED THROUGH
*     THE FIRST TWO WORDS OF EACH BLOCK - 
*         WORD1 -  LENGTH OF BLOCK
*         WORD2 - ADDRESS OF NEXT BLOCK (OR 77777 IF THIS IS LAST BLOCK)
* 
*     THE ALLOCATOR 'TRANSFERS' THE UPPER END OF A BLOCK TO IOC AND 
*     SHORTENS THE LENGTH OF THE BLOCK BY THE AMOUNT 'TRANSFERRED'
* 
* 
*     REGISTERS ARE NOT PRESERVED 
* 
      SKP 
$ALC  JMP ALCIN     INIT (FROM $STRT, RETURNS TO $WORK) 
      LDA $ALC,I    GET THE LENGTH OF THE REQUEST 
      STA ADX       AND SAVE IT 
      STA XTEMP,I    SAVE IN ID SEG IN CASE SUSPEND 
      LDB A 
      ADA AVMEM      ENOUGH MEMORY NOW
      SSA             TO HONOR THE REQUEST? 
      JMP .A1         YES, GO ALLOCATE. 
      ADB MAXEV 
      SSB,RSS          WHAT ABOUT LATER?
      JMP ERETN          NEVER! 
      ISZ $ALC           MAYBE, BUT NOT NOW.
REJ   CLA,CLE,RSS   A=0, E=0 NOT NOW
ERETN CCA,CLE       A=-1,E=0 NOT EVER 
      JMP SETB      RETURN
* 
.A1   ISZ $ALC      TRY AN ALLOCATION 
      CCA           SET CORE AVAIL. NOW TO 0
      STA ALCIN 
      LDB PNTRA     START THE SEARCH LOOP WITH
.A2   STB BAD        SET LAST BUFFER ADDRESS
      CLE,INB        STEP TO THE NEXT ADDRESS 
      LDB B,I       GET THE NEXT SEGMENT ADDRESS
      CPB M7        IF 77777 THEN END OF LIST AND NO
      JMP NOMOR      MEMORY SO REJECT 
      LDA B,I       CHECK TO SEE IF THIS IS THE 
      ADA ALCIN      LARGEST LENGTH SO FAR
      LDA B,I       GET THE LENGTH
      CMA,SEZ       SET NEG(-1) AND IF
      STA ALCIN      LARGEST SO FAR SAVE
      ADA ADX       WILL IT SATISFY THE REQUEST?
      CMA,SSA       IF ZERO OR NEGATIVE USE IT
      JMP .A2        ELSE GO TRY NEXT ONE 
      ADA DM2       IS BLOCK AT LEAST 2 WORDS 
      CCE,SSA        LARGER THAN REQUEST? 
      JMP .A4        NO-ALLOCATE WHOLE BLOCK
      ADA D2        (A)=LENGTH(I)-L(X)
      STA B,I       SET NEW L(I)
      ADA B         (A)=BUFFER ADDRESS
      JMP SETA      RETURN TO USER
* 
.A4   LDA B,I       ALLOCATE ENTIRE BLOCK.
      STA ADX       SET BUFFER LENGTH 
      STB A         BUFFER ADDRESS TO A 
      CCE,INB       SET E FOR ACCEPTED RETURN 
      LDB B,I       GET THE POINTER TO THE NEXT BLOCK 
      ISZ BAD       STEP TO POINTER ADDRESS IN LAST 
      STB BAD,I     BLOCK AND SET THE POINTER 
SETA  ISZ $ALC
SETB  LDB MAXEV     SET B FOR REJECT
      SZA,RSS       IF JUST FOR NOW RESET TO MAX
      LDB AVMEM     AVAILABLE NOW 
      CMB,SEZ       SET POSITIVE AND IF REQUEST 
      LDB ADX       SATISFIED SET TO LENGTH 
      ISZ $ALC     STEP RETURN ADDRESS
      JMP $ALC,I   AND RETURN 
* 
NOMOR LDA ALCIN     PICK UP MAX LEFT DURING SEARCH
      STA AVMEM     UPDATE MAX AVAILABLE NOW
      JMP REJ       NOW RETURN
* 
* 
$RTN NOP           ENTRY POINT FOR BUFFER RETURN
      LDA $RTN,I   (A) = FWA RETURN BUFFER (ADX)
      STA ADX 
      CMA,INA       SET NEG AND 
      STA SAVA      SAVE
      ISZ $RTN
      LDA $RTN,I   # OF WORDS RETURNED (X)
      ADA DM2 
      SSA           <2? 
      JMP RETNR     BUFFER TO SMALL - IGNORE
      LDA PNTRA     GET THE STARTING POINTER
.R11  STA BAD       BAD _ AAD 
      INA 
      LDB A,I       AAD _ NEXTBUFAD 
      STB A         A _ PNTR
      ADB SAVA      AAD -ADX
      CMB,SSB,INB,SZB  ADX-AAD>=0?
      RSS            SKIP IF FOUND
      JMP .R11       ELSE CONTINUE
* 
* 
* 
      LDB BAD       GET LOWER BUFFER ADDRESS
      CPB PNTRA     IF LOCAT POINTER
      JMP .R3       ASSUME NO OVERLAP 
      ADB B,I       ADD LENGTH AND
      ADB SAVA      SUBTRACT THE NEW BLOCK ADDRESS
      CMB,SSB,INB,RSS  IF NEG NO OVERLAP SO 
      JMP .R3           JUMP
      ADB $RTN,I     ELSE COMPUTE NEW LENGTH
      ADB BAD,I     NOW HAVE NEW +OLD-OVERLAP 
.R4   STB BAD,I     SET LENGTH ;CHECK FOR HIGH OVER-
      ADB BAD        LAP COMPUTE END OF BLOCK 
      CMB,CLE,INB    AND SUBTRACT FROM THE HIGH BLOCK 
      ADB A         A HAS HIGH BLOCK ADDRESS
      SEZ,CLE,SZB   IF RESULT POSITIVE
      JMP .R5        JUMP 
      ADB A,I       ADD OLD UPPER LENGTH
      ADB BAD,I      CURRENT LENGTH 
      STB BAD,I     NEW+OLD-OVERLAP 
      CLE,INA       GET POINTER AND BRING 
      LDA A,I        DOWN TO NEW BLOCK
.R5   LDB BAD,I     SAVE MAX LENGTH THIS RETURN 
      ISZ BAD       STEP TO POINTER ADRRESS 
      STA BAD,I     SET THE POINTER 
      LDA AVMEM     CHECK TOO SEE IF THIS LENGTH
      ADA B          ADD CURRENT MAX
      CMB,SEZ,CLE   SET NEG; NEW MAX? 
      STB AVMEM      YES; SET IT
RETNR ISZ $RTN
MEM16 LDB SUSP3     GET SUSPENSION LIST PTR 
      SZB,RSS       IF END OF LIST
      JMP $RTN,I     RETURN.
* 
      LDA B 
      INA            PICK UP XTEMP,I FOR
      LDA A,I        BLOCK SIZE REQUESTED.
      ADA AVMEM     COMPARE TO MAX NOW
      CMA,SSA,INA,SZA   ENOUGH YET? 
      JMP $RTN,I     NO, TOO BAD. 
      JSB $LIST      YES, SCHEDULE PROGRAM. 
      OCT 401 
      JMP MEM16     TRY NEXT PROGRAM TOO. 
* 
.R3   ISZ BAD       NO LOW OVERLAP SET NEW BLOCK
      LDB ADX       ADDRESS IN LOW BLOCK
      STB BAD,I     TO LINK THE BLOCKS
      STB BAD       SET POINTER FOR HIGH BLOCK CHECK
      LDB $RTN,I   SET B TO THE LENGTH OF RETURN
      JMP .R4       CHECK FOR HIGH OVERLAP
* 
* 
* 
PNTRA DEF AVMEM     DUMMY BLOCK ADDRESS(DON'T MESS!)
AVMEM OCT -1        DUMMY BLOCK LENGTH (NOT USED) 
$PNTR OCT 77777     DUMMY BLOCK END    (DON'T MESS!)
BAD   NOP 
SAVA  NOP 
M7    OCT 77777 
DM2   OCT -2
D2    OCT 2 
ADX   NOP 
* 
ALCIN LDA AVMEM     INITIALIZATION CODE 
MAXEV STA *         MAX SIZE BLOCK EVER AVAILABLE 
      JMP $WORK     JMP TO NEXT STARTUP ROUTINE 
* 
A     EQU 0 
B     EQU 1 
SUSP3 EQU 1714B 
XTEMP EQU 1721B 
* 
      BSS 0          LENGTH OF PROGRAM
* 
      END $ALC
                                                                            