*USE 'ASMB,R,N' (RTE-M I/RTE-M II) OR 'ASMB,R,Z' (RTE-M III)
* 
*     IFN OPTION
*     NAME:   $MBU
*     SOURCE: 92064-18010 
*     RELOC:  92064-16005 AND ALSO PART OF 92064-16002  
*     PROGMR: E.J.W.  BASED ON RTE-III VERSIONS G.A.A.,L.W.A.,D.L.S.
* 
*     IFZ OPTION
*     NAME  : $MBU3 
*     SOURCE: 92064-18010 
*     RELOC:  PART OF 92064-16003 
*     PROGMR: E.J.W.  BASED ON RTE-III VERSIONS G.A.A.,L.W.A.,D.L.S.
* 
*  **************************************************************** 
*  * (C) COPYRIGHT HEWLETT-PACKARD COMPANY 1976.  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.        * 
*  **************************************************************** 
* 
* 
      IFN 
* BEGIN NON-DMS CODE ***************
      NAM $MBU,0  92064-16005  REV.1650  761020 
*** END NON-DMS CODE ***************
      XIF 
      IFZ 
***** BEGIN DMS CODE ***************
      NAM $MBU3,0  92064-16003  REV.1650  761020
******* END DMS CODE ***************
      XIF 
      SPC 1 
      ENT $QCHK 
      ENT $ALC,$RTN 
      EXT $LIST,$WORK,$MIC
* 
*     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, - (SMEM ) - 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 
      SKP 2 
$ALC  JMP ALCIN     INIT (FROM $STRT, RETURNS TO $WORK) 
      SPC 1 
      IFZ 
***** BEGIN DMS CODE ***************
      RSA           STORE MEU STATUS IN MEM 
      RAL,RAL 
      STA DMSST 
      SJP *+2 
******* END DMS CODE ***************
      XIF 
      SPC 1 
      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 SMEM       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 
.INB  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 SMEM      AVAILABLE NOW 
      CMB,SEZ       SET POSITIVE AND IF REQUEST 
      LDB ADX       SATISFIED SET TO LENGTH 
      ISZ $ALC     STEP RETURN ADDRESS
      SPC 1 
      IFN 
* BEGIN NON-DMS CODE ***************
      JMP $ALC,I    RETURN
*** END NON-DMS CODE ***************
      XIF 
      SPC 1 
      IFZ 
***** BEGIN DMS CODE ***************
      JRS DMSST $ALC,I RETURN, RESTORE STATUS TO MEU
DMSST NOP 
******* END DMS CODE ***************
      XIF 
      SPC 1 
* 
NOMOR LDA ALCIN     PICK UP MAX LEFT DURING SEARCH
      STA SMEM      UPDATE MAX AVAILABLE NOW
      JMP REJ       NOW RETURN
* 
* 
$RTN NOP           ENTRY POINT FOR BUFFER RETURN
      SPC 1 
      IFZ 
***** BEGIN DMS CODE ***************
      RSA           STORE MEU STATUS
      RAL,RAL 
      STA DMSST 
      SJP *+2 
******* END DMS CODE ***************
      XIF 
      SPC 1 
      LDA $RTN,I   (A) = FWA RETURN BUFFER (ADX)
      STA ADX 
      CMA,INA       SET NEG AND 
      STA SAVA      SAVE
      ISZ $RTN
* 
      LDB $RTN,I   # OF WORDS RETURNED (X)
      ADB DM2 
      SSB           <2? 
      JMP RETNR     BUFFER TOO SMALL - IGNORE 
MIC1  JMP NMIC1 
      LDB PNTRA     GET THE STARTING POINTER
      OCT 105627    CALL MICRO. (A)=-ADDR,(B)=PNTRA 
      STB BAD 
      JMP .R12
* 
NMIC1 LDA PNTRA     GET STARTING POINTER
.R11  STA BAD       BAD _ AAD 
NMIC3 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
.R12  CPB PNTRA     IF LOCATE POINTER 
      JMP .R3        ASSUME NO OVERLAP
      ADB B,I       ADD LENGTH AND
      ADB SAVA       SUBTRACT 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 SMEM      CHECK TOO SEE IF THIS LENGTH
      ADA B          ADD CURRENT MAX
      CMB,SEZ,CLE   SET NEG; NEW MAX? 
      STB SMEM       YES; SET IT
RETNR ISZ $RTN
MEM16 LDB SUSP3     GET SUSPENSION LIST PTR 
      SZB,RSS       IF END OF LIST
      JMP MPRTN      RETURN.
* 
      LDA B 
      INA            PICK UP XTEMP,I FOR
      LDA A,I        BLOCK SIZE REQUESTED.
      ADA SMEM      COMPARE TO MAX NOW
      CMA,SSA,INA,SZA   ENOUGH YET? 
      JMP MPRTN      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
* 
MPRTN EQU * 
      SPC 1 
      IFN 
* BEGIN NON-DMS CODE ***************
      JMP $RTN,I    RETURN
*** END NON-DMS CODE ***************
      XIF 
      SPC 1 
      IFZ 
***** BEGIN DMS CODE ***************
      JRS DMSST $RTN,I   RETURN, RESTORE DMS STATUS 
******* END DMS CODE ***************
      XIF 
      SPC 1 
* 
* 
PNTRA DEF SMEM      DUMMY BLOCK ADDRESS(DON'T MESS!)
SMEM  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 SMEM      INITIALIZATION CODE 
MAXEV STA *         MAX SIZE BLOCK EVER AVAILABLE 
TEMP1 CLB 
TEMP2 LDA $MIC
      SZA           DO WE HAVE MICROCODE? 
      STB MIC1       YES
      JMP $WORK     JMP TO NEXT STARTUP ROUTINE 
* 
A     EQU 0 
B     EQU 1 
SUSP3 EQU 1714B 
XTEMP EQU 1721B 
* 
* 
*     THE QUEUE CHECK ROUTINE CHECKS TO SEE IF THE QUEUE ON 
*     THE CURRENT EQT HAS MORE THEN THE 'LIMIT' NUMBER OF WORDS 
*     OF BUFFER MEMORY ON IT AT THE CURRENT TIME. 
*     THE LIMIT IS PASSED IN THE B-REG. SO THE ROUTINE CAN
*     CAN BE USED FOR BOTH UPPER AND LOWER LIMIT CHECKS.
*           CALLING SEQUENCE: 
*     LDB NEGATIVE OF LIMIT 
*     JSB QCHK
*     --- MORE THAN LIMIT WORDS ON QUEUE
*     --- LESS THAN LIMIT WORDS ON QUEUE
*     EQT1 ADDRESS IS IN B ON EXIT
* 
$QCHK NOP 
      SPC 1 
      IFZ 
***** BEGIN DMS CODE ***************
      RSA 
      RAL,RAL 
      SJP *+2       SJP SO WE CAN SEE S.A.M.
      STA DMSST     SAVE DMS STATUS 
******* END DMS CODE ***************
      XIF 
      SPC 1 
      STB TEMP1     SET LIMIT 
      LDA EQT1,I    START AT EQT HEAD 
      RAL,CLE,ERA   CLEAR POSSIBLE SIGN BIT 
      CLE,SZB       INIT E=0, SKIP CHECK IF 0 LIMIT 
QCHK1 SZA,RSS       END OF QUEUE? 
      JMP QCHK3     YES GO EXIT 
* 
      STA TEMP2     SET CURRENT ELEMEMT 
      INA           GET THE CON WORD
      LDB A,I       TO B
      RBL CHECK IF A BUFFERED 
      SSB,RSS       REQUEST?
      JMP QCHK2     NO TRY NEXT ONE 
* 
      ADA D2        YES STEP TO THE COUNT 
      LDB A,I       GET COUNT TO B
      ADB TEMP1     ADD TO LIMIT
      STB TEMP1     AND RESET 
QCHK2 LDA TEMP2,I   GET NEXT ELEMENT
      JMP QCHK1     GO CHECK THIS ELEMENT 
* 
QCHK3 LDB EQT1      GET SUSPEND POINTER 
      SEZ,RSS       OVERFLOW? 
      ISZ $QCHK     NO  STEP RETURN 
      SPC 1 
      IFN 
* BEGIN NON-DMS CODE ***************
      JMP $QCHK,I   RETURN
*** END NON-DMS CODE ***************
      XIF 
      SPC 1 
      IFZ 
***** BEGIN DMS CODE ***************
      JRS DMSST $QCHK,I RETURN
******* END DMS CODE ***************
      XIF 
      SPC 1 
      SPC 4 
EQT1  EQU 1660B 
* 
      BSS 0         SIZE OF MODULE
      END 
          