ASMB,Q,C
* 
*  ***************************************************************
*  * (C) COPYRIGHT HEWLETT-PACKARD COMPANY 1979.  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.       *
*  ***************************************************************
* 
*     SOURCE PART NUMBER : 92067-18311
* 
*     RELOCATABLE PART NUMBER : 92067-16268 
* 
*     PROGRAMER(S)   : J.M.N. 
* 
* 
      NAM $BALC,7 92067-1X311 REV.2013 791016 
      ENT $BALC,$BRTN 
      EXT $BRTX,$OSAM,$PNTI,$MAXI 
      EXT $LIBR,$LIBX,.ENTR 
* 
* 
*     THIS ROUTINE ALLOCATES AND RETURNS A BLOCK OF 
*     SAM SEMI PERMENANTLY. 
*     THE ALGORITHM IS DESIGNED TO LEAVE THE LARGEST
*     CONTIGUOUS $BOCK POSIBLE IN SAM.
* 
*     ALTHOUGH THERE IS NO LIMIT TO NUMBER OF BLOCKS
*     THAT CAN BE ALLOCATED, $OSAM ONLY HAS ROOM FOR
*     4 BLOCKS. 
* 
* 
*     CALLING SEQUENCE: 
* 
*       LDA IWRDS 
*       STA NWRDS        SET NWORDS TO NO OF WORDS REQUIRED 
*       JSB $BALC 
*       DEF *+4 
*       DEF NWRDS 
*       DEF IADDR   ADDRESS RETURNED OF START OF BLOCK
*       DEF MAXEV   LARGEST CONTIGUIOUS BLOCK LEFT IN SAM 
* 
* 
* 
*     TO RETURN MEMORY
*      THE CALLING SEQUENCE IS: 
* 
*       JSB $BRTN 
*       DEF *+3 
*       DEF IADDR 
*       DEF NWRDS 
* 
*     WHERE: NWORDS  IS BUFFER SIZE IN WORDS
*            IADDR   IS ADDRESS OF BUFFER 
*            MAXEV   IS THE LARGEST POSIBLE 
*                    $BOCK LEFT IN SAM
* 
* 
P01   NOP 
P02   NOP 
P03   NOP 
$BALC NOP 
      JSB .ENTR 
      DEF P01 
* 
      XLA $PNTI+0   SET UP POINTERS TO SAM
      ADA DM1 
      STA PNTRA 
      XLA $MAXI     POINTER TO MAXEV
      STA $MAXE 
* 
      LDA M7        SET MINIMUN BLOCK 
      STA MINBK 
      CLA           AND LARGEST OFFSET
      STA SOFST 
      LDA P01,I     GET REQUEST SIZE
      CMA,INA 
      STA RWRDS 
* 
      JSB $LIBR     MUST SHUT DOWN TO SCAN LIST 
      NOP 
      LDB PNTRA     GET START OF FREE LIST
      RSS 
LOOP1 XBX           PUT SAM POINTER IN B REG
      JSB NSAM      GET NEXT SAM ENTRY
      JMP BEST      SCANED THE LIST GO TAKE BEST
      CMA,INA       SAVE THE NEGATIVE OF LAST ADDRESS+1 
      STA LADDR 
      XBX           SAVE LIST POINTER IN X
      LDB ORGPT     POINTER TO ORIGINAL BLOCK DESCRIPTOR
LOOP2 JSB OSAM      GET ORIGINAL BLOCK
      JMP LOOP1     NO QUALIFIED BLOCK
      JMP LOOP2     EMPTY ENTRY IGNOR 
      ADA LADDR     COMPUTE BACK OFFSET 
      SSA 
      JMP LOOP2     IF NEGATIVE NOT IN BLOCK
      STA BOFST 
* 
      LDA OADDR 
      CMA,INA       COMPUTE FRONT OFFSET
      ADA SADDR 
      SSA 
      JMP LOOP2     IF NEGATIVE NOT IN BLOCK
      STA FOFST 
* 
*     SAM IS IN CURRENT BLOCK 
* 
      ADB DM2       ADJUST POINTER TO CURRENT BLOCK 
* 
      LDA OWRDS     UPDATE MINIMUM BLOCK
      CMA,INA 
      STA MINBK 
* 
      LDA FOFST     COMPUTE LARGEST OFFSET
      CMA,INA 
      ADA BOFST 
      CCE,SSA 
      CLA,CLE 
      ADA FOFST 
      STA OFFST     SAVE LARGEST OFFSET 
      ERA           SAVE WHICH SIDE 
      STA FORB      POS = FRONT,NEG = BACK
      ELA 
* 
      ADA SOFST     IS IT LARGEST SO FAR
      SSA 
      JMP LOOP1     NO GO GET NEXT
* 
*     BEST FIT SO FAR 
* 
* 
* 
*                   TRANSFER PARAMETERS 
* 
      STB SPNTR             BLOCK POINTER 
      ISZ SPNTR     ADJUST SPNTR TO POINT TO BLOCK
      STX NLINK        NEXT LINK
      LDA OFFST        NEGATIVE OF LARGEST OFFSET 
      CMA,INA 
* 
      LDB TRPNT 
      STA B,I 
      INB 
LOOP3 CPB TREND 
      JMP LOOP1     FINISHED GO GET NEXT
      LDA B,I 
      INB 
      STA B,I 
      INB 
      JMP LOOP3 
* 
* 
*     THIS IS THE BEST ALLOCATION 
* 
BEST  LDA MINBK     WAS ANY SAM FOUND?
      CPA M7
      JMP ERROR     NO GO REPORT ERROR
* 
      LDA RWRDS     IF THERE IS LESS THAN 
      ADA SWRDS+1 2 EXTRA WORDS 
      ADA DM2 
      LDB SWRDS+1 
      CMB,INB 
      SSA 
      STB RWRDS     THEN USE WHOLE BLOCK
* 
      LDA SWRDS+1 
      ADA RWRDS     COMPUTE WODRS LEFT
      LDB FORB+1
      SSB,RSS       SHOULD WE USE FRONT OR BACK 
      JMP BPART     (USE BACK)
      LDB RWRDS     COMPUTE ADDRESS OF BLOCK LEFT 
      CMB,INB 
      ADB NLINK 
      XSB LLINK+1,I AND FIX LAST LINK 
      XAX           SAVE WORD COUNT IN X
      ISZ NLINK 
      XLA NLINK,I   GET NEXT LINK 
      XAX           FIX WORD COUNT
      XSA B,I 
      XAX 
      INB 
      XSA B,I       AND NEXT LINK 
      CCA           SET TO RESET NLINK
      JMP BP.1
* 
*     BACK PART 
* 
BPART XSA NLINK,I   UPDATE WORD COUNT 
BP.1  ADA NLINK     FIX NLINK 
      STA NLINK 
* 
*     REMOVE FROM ORIGINAL DESCRIPTION
* 
      LDA OADDR+1 
      CMA,INA 
      ADA NLINK 
      XSA SPNTR,I   (MAYBE FREE AN ENTRY) 
* 
      CMA,INA 
      ADA OWRDS+1 
      ADA RWRDS 
      STA OWRDS+1 
      LDB ORGP
RM.2  XLA B,I       FIND FREE ENTRY 
      SZA,RSS 
      JMP RM.3
      ADB D2
      JMP RM.2
* 
RM.3  LDA OWRDS+1   PUT WORDS IN ENTRY
      XSA B,I 
      INB 
      LDA RWRDS     SEND BACK ACTUAL WORD COUNT 
      CMA,INA 
      STA P01,I 
      ADA NLINK     COMPUTE START ADDRESS FREE BLOCK
      XSA B,I 
* 
*     PASS ADDRESS AND MAXEV
*     BACK TO PROGRAM 
* 
      LDA NLINK 
      STA P02,I 
      LDA RWRDS 
      CMA,INA 
RM.4  STA P01,I 
* 
      JSB MXEV      GO UPDATE MAXEV 
      STA P03,I     MAXEV 
* 
      JSB $LIBX 
      DEF $BALC 
* 
ERROR CCA           RETURN -1 WORDS 
      JMP RM.4
* 
*     CONSTANTS AND VARIABLES 
* 
PNTRA BSS 1 
$MAXE BSS 1 
ORGPT DEF $OSAM-1 
ORGP  DEF $OSAM+0 
* 
A     EQU 0 
B     EQU 1 
* 
OFFST BSS 1 
SOFST BSS 1 
OWRDS BSS 2 
SWRDS BSS 2 
FORB  BSS 2 
LLINK BSS 2 
OADDR BSS 2 
NLINK BSS 1 
SADDR BSS 1 
BOFST BSS 1 
FOFST BSS 1 
RWRDS BSS 1 
SPNTR BSS 1 
LADDR BSS 1 
TRPNT DEF SOFST 
TREND DEF NLINK 
D2    DEC 2 
DM1    DEC -1 
DM2    DEC -2 
M7    OCT 77777 
MINBK OCT 77777 
* 
* 
*     RETURN BLOCK  TO SAM
* 
P1    NOP 
P2    NOP 
$BRTN NOP 
      LDA $BRTN 
      STA P1
      INA 
      STA P2
      INA 
      STA $BRTN 
      CLA 
      STA SPNTR     CLEAR SPNTR 
      LDA M7        SET MINBK TO MAX
      STA MINBK 
      LDA P2,I      GET NO OF WORDS 
      STA RWRDS 
      LDA P1,I      GET START ADDRESS 
      STA NLINK 
      ADA P2,I      COMPUTE LAST ADDRESS+1
      STA LADDR 
      JSB $LIBR     MUST GO PRIVELEGED
      NOP 
* 
      LDB ORGPT 
BR.0  JSB OSAM      FIND BLOCK
      JMP BR.4      WE'RE DONE
      JMP BR.3      IGNOR EMPTY ENTRIES 
      CPA NLINK     DOES IT MATCH IN FRONT
      JMP BR.1      YES GO ADD IT 
      LDA LADDR 
      CPA OADDR     NO,DOES IT MATCH IN BACK
      JMP BR.2      YES GO ADD IT 
      JMP BR.0      NO GO GET NEXT BLOCK
* 
* 
BR.1  LDA OADDR     UPDATE STARTING 
      STA NLINK 
* 
BR.2  LDA RWRDS     UPDATE WORDS COUNT
      ADA OWRDS 
      STA RWRDS 
* 
BR.3  ADB DM1       SET POINTER BACK
      LDA SPNTR     IF SPNTR NOT SET UP 
      SZA,RSS 
      STB SPNTR     THEN SET IT 
* 
      CLA 
      XSA B,I       CLEAR ENTRY (MAY BE SET LATER)
      INB           RESET POINTER 
      JMP BR.0      GO GET NEXT BLOCK 
* 
*     PUT NEW ENTRY IN BLOCK
* 
BR.4  LDB SPNTR 
      SZB,RSS       IF SPNTR NOT SET UP 
      JMP BR.5      GO TO END 
* 
      LDA RWRDS 
      XSA B,I       PUT IN WORDS
      INB 
      LDA NLINK 
      XSA B,I 
* 
      JSB MXEV      UPDATE MAXEV
      LDA P1,I
      LDB P2,I
      SJS $BRTX+0 
BR.5  JSB $LIBX 
      DEF $BRTN 
* 
* 
*     NSAM RETRIEVES NEXT 
*     BLOCK IN SAM
* 
*     CALLING SEQUENCE
* 
*       LDB PNTRA      ADDRESS OF FREE LIST 
*       JSB NSAM
*       . . .         END OF LIST RETURN
*       . . .         FOUND BLOCK RETURN
* 
NSAM  NOP 
NS.1  CLE,INB       BUMP TO LINK
      STB LLINK     SAVE LAST LINK
      XLB B,I       GET NEXT LINK 
      CPB M7        IF 77777B THEN END OF FREE LIST 
      JMP NSAM,I
* 
      XLA B,I       GET LENGTH OF BLOCK 
      STA SWRDS 
      ADA RWRDS     IS IT BIG ENOUGH? 
      SSA 
      JMP NS.1      NO GO GET NEXT
* 
      STB SADDR     YES, SAVE ADDRESS 
      LDA SWRDS 
      ADA B         COMPUTE LAST ADDRESS+1
      ISZ NSAM      ADJUST FOR NORMAL RETURN
      JMP NSAM,I
* 
* 
*     OSAM FINDS THE NEXT BLOCK 
*     OF ORIGINAL SAM 
* 
*     CALLING SEQUENCE: 
* 
*       LDB ORGPT 
*       JSB OSAM
*     . . .           FINISHED SCANNING ORG STRUCTURE 
*     . . .           EMPTY ENTRY 
*     . . .           FOUND NEXT BLOCK
* 
* 
OSAM  NOP 
      INB 
      XLA B,I       GET # OF WORDS IN BLOCK 
      INB 
      SSA           IF NEGATIVE 
      JMP OSAM,I    THEN END OF TABLE (DONE)
      ISZ OSAM
      SZA,RSS       IF ZERO THEN EMPTY
      JMP OSAM,I
      STA TEMP
      ADA MINBK     IS IT SMALLER THAN ACCEPTABLE 
      SSA,RSS       BLOCK 
      JMP OSAM,I    NO REJECT 
* 
      ISZ OSAM
      LDA TEMP
      STA OWRDS 
      XLA B,I       GET ADDRESS 
      STA OADDR 
      ADA OWRDS     COMPUTE LAST ADDRESS+1
      JMP OSAM,I
* 
* 
*     MMXEV POSTS THE NEW MAXEV 
* 
*     CALLING SEQUENCE: 
*       JSB MXEV
*       . . .         A REG =MAXEV
* 
MXEV  NOP 
      LDB ORGP
      CLA           CLEAR MAXEV 
MXEV1 STA MAXEV 
      XLA B,I       GET LENGTH OF NEXT BLOCK
      ADB D2        BUMP BLOCK POINTER
      SSA           IF LENGTH IS NEGATIVE 
      JMP MXEV2     THEN AT END OF OSAM 
* 
      ADA MAXEV     SUBTRACT MAXEV FROM BLOCK LENGTH
      CMA,SSA,INA,RSS IF MAXEV>BLOCK LENGTH  A REG IS POS 
*                                 IF MAXEV>BLOCK LENGTH 
      CLA           THEN RESTORE MAXEV
      ADA MAXEV     ELSE SET MAXEV TO BLOCK LENGTH
      JMP MXEV1 
* 
MXEV2 LDA MAXEV     GET BIGGEST 
      XSA $MAXE,I   COMPLIMENT AND STUFF
      CMA,INA       MAKE POSITIVE 
      JMP MXEV,I
TEMP  BSS 1 
MAXEV BSS 1 
* 
      END 
                                                                                                                                                                                                                                  