Twenex Muddle.
[pdp10-muddle.git] / <mdl.int> / stbuil.mid.18
diff --git a/<mdl.int>/stbuil.mid.18 b/<mdl.int>/stbuil.mid.18
new file mode 100644 (file)
index 0000000..e5269f5
--- /dev/null
@@ -0,0 +1,2133 @@
+
+ TITLE STRBUILD MUDDLE STRUCTURE BUILDER
+
+.GLOBAL RCL,VECTOP,GCSTOP,GCSBOT,FRETOP,GCSNEW,VECBOT,PARTOP,PARBOT,HITOP,HIBOT,GETPAG
+.GLOBAL PDLBUF,PDLEX,PDLEXP,GCFLG,GCPDL,GETNUM,PARNEW,MOVPUR,RCLV,RCLVEC
+.GLOBAL PGROW,TPGROW,MAINPR,%SLEEP,MSGTYP,PURTOP,PURBOT,STOSTR,RBLDM,CPOPJ,CPOPJ1,STBL
+.GLOBAL MTYI,UPLO,FRMUNG,BYTDOP,GLOBSP,FREDIF,FREMIN,GCHAPN,INTFLG,PINIT,CKPUR,GCSET
+.GLOBAL SAT,TTOCHN,TYPVEC,ICONS,INCONS,IBLOCK,IEUVEC,IEVECTI,CELL2,MKTBS,CPOPJ1,.LIST.
+.GLOBAL GIBLOK,REHASH,IBLOK1,IILIST,IIFORM,CIVEC,CIUVEC,CICONS,SLEEPR,GCHK10,FPAG
+.GLOBAL SPBASE,OUTRNG,CISTNG,CBYTES,%RUNAM,PURVEC,GCDOWN,N.CHNS,CHNL1,PLODR,C1CONS
+.GLOBAL CAFRE,CAFRET,STOGC,GCHN,WNDP,FRNP,FRONT,%GCJOB,%SHWND,%INFMP,%GETIP
+.GLOBAL TD.PUT,TD.GET,TD.LNT,GLOTOP,UBIT,FLGSET,PURMNG,RPURBT,%IFMP2,CHKPGI,PURCLN
+.GLOBAL        CTIME,MTYO,ILOC,NODES,GPURFL,GCDANG,GCHACK,LPUR,HITOP,BADCHN,IMPURX
+.GLOBAL NOWLVL,CURPLN,PVSTOR,SPSTOR,MPOPJ,NGCS,RNUMSP,NUMSWP,SAGC,INQAGC
+.GLOBAL        GCTIM,GCCAUS,GCCALL,AAGC,LVLINC,STORIC,GVLINC,TYPIC,GCRSET,ACCESS,NOSHUF,SQUPNT
+; GLOBALS ASSOCIATE WITH THE ASSOCIATION VECTOR
+
+.GLOBAL ASOVEC,ASOLNT,ITEM,INDIC,VAL,NWORDT,NODPNT,PNTRS
+.GLOBAL CELL,BINDID,GCFLCH,TYPBOT,GLOBAS,TPBASE
+.GLOBAL TPBINC,GBLINC,TYPINC,CONADJ,OGCSTP,ABOTN
+.GLOBAL AGC,ROOT,CIGTPR,IIGLOC
+.GLOBAL P.TOP,P.CORE,PMAPB
+.GLOBAL        %MPINT,%GBINT,%CLSMP,%CLSM1
+.GLOBAL GCKNUM,CORTOP,GCHPN,INTAGC,WNDP,WNDBOT,BUFGC,WIND,GCDFLG,SAVM
+
+; SHARED SYMBOLS WITH GC MODULE
+
+.GLOBAL        GCNO,BSTGC,BSTAT,NOWFRE,CURFRE,MAXFRE,USEFRE,NOWTP,CURTP,CTPMX,NOWLFL
+.GLOBAL        CURLVL,NOWGVL,CURGVL,NOWTYP,CURTYP,NOWSTO,CURSTO,CURMAX,NOWP,CURP,CPMX
+.GLOBAL        GCCAUS,GCCALL,LVLINC,GVLINC,TYPIC,STORIC,RCL,RCLV,GCDANG,GETNUM,RPTOP,CORTOP
+.GLOBAL        TPGROW,PPGROW,PGROW,PMAIN,PGOOD,PMAX,TPGOOD,TPMIN,TPMAX,RFRETP,TYPTAB
+.GLOBAL        NNPRI,NNSAT,TYPSAV,BUFGC,GCTIM,GPURFL,GCDFLG,DUMFLG,PMIN,PURMIN
+.GLOBAL GLBINC,GCHAIR,GCMONF,SQKIL,INBLOT
+.GLOBAL C%11,C%22,C%33,C%44,C%55,C%66,C%0,C%1,C%2,C%3,C%M1,C%M2,C%M10
+.GLOBAL C%M20,C%M30,C%M40,C%M60
+
+NOPAGS==1      ; NUMBER OF WINDOWS
+EOFBIT==1000
+PDLBUF=100
+
+.ATOM.==200000 ; FLAG SAYING ATOMS MARKED (FOR VAL FLUSH LOGIC)
+
+GCHN==0                ; CHANNEL FOR FUNNNY INFERIOR
+STATNO==19.    ; # OF STATISTICS FOR BLOAT-STAT
+STATGC==8.     ; # OF GC-STATISTICS FOR BLOAT-STAT
+
+
+RELOCATABLE
+.INSRT MUDDLE >
+SYSQ
+IFE ITS,[
+.INSRT STENEX >
+]
+IFN ITS,       PGSZ==10.
+IFE ITS,       PGSZ==9.
+
+
+\f; GC-READ TAKES ONE ARGUMENT WHICH MUST BE A "READB" CHANNEL
+
+.GLOBAL CLOOKU,CINSER,MOBLIST,CATOM,EOFCND,IGLOC
+
+MFUNCTION GCREAD,SUBR,[GC-READ]
+
+       ENTRY
+
+       CAML    AB,C%M2         ; CHECK # OF ARGS
+       JRST    TFA
+       CAMGE   AB,C%M40
+       JRST    TMA
+
+       GETYP   A,(AB)          ; MAKE SURE ARG IS A CHANNEL
+       CAIE    A,TCHAN
+       JRST    WTYP2           ; IT ISN'T COMPLAIN
+       MOVE    B,1(AB)         ; GET PTR TO CHANNEL
+       HRRZ    C,-2(B)         ; LOOK AT BITS IN CHANNEL
+       TRC     C,C.OPN+C.READ+C.BIN
+       TRNE    C,C.OPN+C.READ+C.BIN
+       JRST    BADCHN
+
+       PUSH    P,1(B)          ; SAVE ITS CHANNEL #
+IFN ITS,[
+       MOVE    B,[-2,,C]       ; SET UP AOBJN PTR TO READ IN DELIMITING
+                               ;       CONSTANTS
+       MOVE    A,(P)           ; GET CHANNEL #
+       DOTCAL  IOT,[A,B]
+       FATAL GCREAD-- IOT FAILED
+       JUMPL   B,EOFGC         ; IF BLOCK DIDN'T FINISH THEN EOF
+]
+IFE ITS,[
+       MOVE    A,(P)           ; GET CHANNEL
+       BIN
+       MOVE    C,B             ; TO C
+       BIN
+       MOVE    D,B             ; TO D
+       GTSTS                   ; SEE IF EOF
+       TLNE    B,EOFBIT
+       JRST    EOFGC
+]
+
+       PUSH    P,C             ; SAVE AC'S
+       PUSH    P,D
+
+IFN ITS,[
+       MOVE    B,[-3,,C]       ; NEXT GROUP OF WORDS
+       DOTCAL  IOT,[A,B]
+       FATAL   GCREAD--GC IOT FAILED
+]
+IFE ITS,[
+       MOVE    A,-2(P)         ; GET CHANNEL
+       BIN
+       MOVE    C,B
+       BIN
+       MOVE    D,B
+       BIN
+       MOVE    E,B
+]
+       MOVEI   0,0             ; DO PRELIMINARY TESTS
+       IOR     0,A             ; IOR ALL WORDS IN
+       IOR     0,B
+       IOR     0,C
+       IOR     0,(P)
+       IOR     0,-1(P)
+       TLNE    0,-1            ; SKIP IF NO BITS IN LEFT HALF
+        JRST   ERDGC
+
+       MOVEM   D,NNPRI
+       MOVEM   E,NNSAT
+       MOVE    D,C             ; GET START OF NEWTYPE TABLE
+       SUB     D,-1(P)         ; CREATE AOBJN POINTER
+       HRLZS   D
+       ADDI    D,(C)
+       MOVEM   D,TYPTAB        ; SAVE IT
+       MOVE    A,(P)           ; GET LENGTH OF WORD
+       SUBI    A,CONADJ        ; SUBTRACT FOR CONSTANTS
+
+       ADD     A,GCSTOP
+       CAMG    A,FRETOP        ; SEE IF GC IS NESESSARY
+       JRST    RDGC1
+       MOVE    C,(P)
+       ADDM    C,GETNUM        ; MOVE IN REQUEST
+       MOVE    C,[0,,1]        ; ARGS TO GC
+       PUSHJ   P,AGC           ; GC
+RDGC1: MOVE    C,GCSTOP        ; GET CURRENT TOP OF THE WORLD
+       MOVEM   C,OGCSTP        ; SAVE IT
+       ADD     C,(P)           ; CALCULATE NEW GCSTOP
+       ADDI    C,2             ; SUBTRACT FOR CONSTANTS
+       MOVEM   C,GCSTOP
+       SUB     C,OGCSTP
+       SUBI    C,2             ; SUBSTRACT TO GET RID OF D.W'S
+       MOVNS   C               ; SET UP AOBJN PTR FOR READIN
+IFN ITS,[
+       HRLZS   C
+       MOVE    A,-2(P)         ; GET CHANNEL #
+       ADD     C,OGCSTP
+       DOTCAL  IOT,[A,C]
+       FATAL GCREAD-- IOT FAILED
+]
+IFE ITS,[
+       MOVE    A,-2(P)         ; CHANNEL TO A
+       MOVE    B,OGCSTP        ; SET UP BYTE POINTER
+       HRLI    B,444400
+       SIN                     ; IN IT COMES
+]
+
+       MOVE    C,(P)           ; GET LENGHT OF OBJECT
+       ADDI    A,5
+       MOVE    B,1(AB)         ; GET CHANNEL
+       ADDM    C,ACCESS(B)
+       MOVE    D,GCSTOP        ; SET UP TO LOOK LIKE UVECTOR OF LOSES
+       ADDI    C,2             ; ADD 2 FOR DOPE WORDS
+       HRLM    C,-1(D)
+       MOVSI   A,.VECT.
+       SETZM   -2(D)
+       IORM    A,-2(D)         ; MARK VECTOR BIT
+       PUSH    TP,$TRDTB       ; HOLD ON IN CASE OF GC
+       MOVEI   A,-2(D)
+       MOVN    C,(P)
+       ADD     A,C
+       HRL     A,C
+       PUSH    TP,A
+
+       MOVE    D,-1(P)         ; SET UP BOTTOM OF ATOM TABLE
+       SUBI    D,1
+       MOVEM   D,ABOTN
+       MOVE    C,GCSTOP        ; START AT TOP OF WORLD
+       SUBI    C,3             ; POINT TO FIRST ATOM
+
+; LOOP TO FIX UP THE ATOMS
+
+AFXLP: HRRZ    0,1(TB)
+       ADD     0,ABOTN
+       CAMG    C,0             ; SEE IF WE ARE DONE
+       JRST    SWEEIN
+       HRRZ    0,1(TB)
+       SUB     C,0
+       PUSHJ   P,ATFXU         ; FIX IT UP
+       HLRZ    A,(C)           ; GET LENGTH
+       TRZ     A,400000        ; TURN OFF MARK BIT
+       SUBI    C,(A)           ; POINT TO PRECEDING ATOM
+       HRRZS   C               ; CLEAR OFF NEGATIVE
+       JRST    AFXLP
+
+; FIXUP ROUTINE FOR ATOMS (C==> D.W.)
+
+ATFXU: PUSH    P,C             ; SAVE PTR TO D.W.
+       ADD     C,1(TB)
+       MOVE    A,C
+       HLRZ    B,(A)           ; GET LENGTH AND MARKING
+       TRZE    B,400000        ; TURN OF MARK BIT AND SKIP IF WAS ALREADY MARKED
+       JRST    ATFXU1
+       MOVEI   D,-3(B)         ; FULL WORDS OF STRING IN PNAME
+       IMULI   D,5             ; CALCULATE # OF CHARACTERS
+       MOVE    0,-2(A)         ; GET LAST WORD OF STRING
+       SUBI    A,-1(B)         ; LET A POINT TO OBLIST SLOAT
+       MOVE    B,A             ; GET COPY OF A
+       MOVE    A,0
+       SUBI    A,1
+       ANDCM   0,A
+       JFFO    0,.+1
+       HRREI   0,-34.(A)
+       IDIVI   0,7             ; # OF CHARS IN LAST WORD
+       ADD     D,0
+       ADD     D,$TCHSTR       ; MAKE IT LOOK LIKE A STRINGS TYPE-WORD
+       PUSH    P,D             ; SAVE IT
+       MOVE    C,(B)           ; GET OBLIST SLOT PTR
+ATFXU9:        HRRZS   B               ; RELATAVIZE POINTER
+       HRRZ    0,1(TB)
+       SUB     B,0
+       PUSH    P,B
+       JUMPE   C,ATFXU6        ; NO OBLIST.  CREATE ATOM
+       CAMN    C,C%M1          ; SEE IF ROOT ATOM
+       JRST    RTFX
+       ADD     C,ABOTN         ; POINT TO ATOM
+       PUSHJ   P,ATFXU
+       PUSH    TP,$TATOM
+       PUSH    TP,B
+       MOVE    A,$TATOM        ; SET UP TO SEE IF OBLIST EXITS
+       MOVE    C,$TATOM
+       MOVE    D,IMQUOTE OBLIST
+       PUSHJ   P,CIGTPR
+       JRST    ATFXU8          ; NO OBLIST. CREATE ONE
+       SUB     TP,C%22         ; GET RID OF SAVED ATOM
+RTCON: PUSH    TP,$TOBLS
+       PUSH    TP,B
+       MOVE    C,B             ; SET UP FOR LOOKUP
+       MOVE    A,-1(P)         ; SET UP PTR TO PNAME
+       MOVE    B,(P)
+       ADD     B,[440700,,1]   ; ADJUST TO MAKE IT LOOK LIKE A BYTE-POINTER
+       HRRZ    0,1(TB)
+       ADD     B,0
+       PUSHJ   P,CLOOKU
+       JRST    ATFXU4          ; NOT ON IT SO INSERT
+ATFXU3:        SUB     P,C%22                  ; DONE
+       SUB     TP,C%22         ; POP OFF OBLIST
+ATFXU7:        MOVE    C,(P)           ; RESTORE PTR TO D.W.
+       ADD     C,1(TB)
+       MOVEM   B,-1(C)         ; MOVE IN RELATAVIZE ADDRESS
+       MOVSI   D,400000
+       IORM    D,(C)           ; TURN OFF MARK BIT
+       MOVE    0,3(B)          ; SEE IF MUST BE LOCR
+       TRNE    0,1             ; SKIP IF MUST MAKE IT IMPURE
+        PUSHJ  P,IIGLOC
+       POP     P,C
+       ADD     C,1(TB)
+       POPJ    P,              ; EXIT
+ATFXU1:        POP     P,C             ; RESTORE PTR TO D.W.
+       ADD     C,1(TB)
+       MOVE    B,-1(C)         ; GET ATOM
+       POPJ    P,
+
+; ROUTINE TO INSERT AN ATOM 
+
+ATFXU4:        MOVE    C,(TP)          ; GET OBLIST PTR
+       MOVE    B,(P)           ; SET UP STRING PTR TO PNAME
+       ADD     B,[440700,,1]
+       HRRZ    0,1(TB)
+       ADD     B,0
+       MOVE    A,-1(P)         ; GET TYPE WORD
+       PUSHJ   P,CINSER        ; INSERT IT
+       JRST    ATFXU3
+
+; THIS ROUTINE CREATS THE ATOM SO THAT ITS NOT ON ANY OBLIST
+
+ATFXU6:        MOVE    B,(P)           ; POINT TO PNAME
+       ADD     B,[440700,,1]   ; MAKE IT LOOK LIKE A BYTE POINTER
+       HRRZ    0,1(TB)
+       ADD     B,0
+       MOVE    A,-1(P)
+       PUSHJ   P,CATOM
+       SUB     P,C%22          ; CLEAN OFF STACK
+       JRST    ATFXU7
+
+; THIS ROUTINE CREATES AND OBLIST
+
+ATFXU8:        MCALL   1,MOBLIST
+       PUSH    TP,$TOBLS
+       PUSH    TP,B            ; SAVE OBLIST PTR
+       JRST    ATFXU4          ; JUMP TO INSERT THE OBLIST
+
+; HERE TO INSERT AN ATOM INTO THE ROOT OBLIST
+
+RTFX:  MOVE    B,ROOT+1                ; GET ROOT OBLIST
+       JRST    RTCON
+
+; THIS ROUTINE SWEEPS THRU THE NEW CORE IMAGE AND UPDATES ALL THE POINTERS.
+
+SWEEIN:
+; ROUTINE TO FIX UP TYPE-TABLE FOR GC-READ. THIS ROUTINE FIXES UP THE TYPE TABLE SO THAT
+; THE TYPES ATOM I.D. IS REPLACED BY ITS TYPE-NUMBER IN THE NEW MUDDLE AND IF ITS A
+; TEMPLATE, THE SLOT FOR THE PRIMTYPE-ATOM IS REPLACED BY THE SAT OF THE TEMPLATE
+
+       HRRZ    E,1(TB)         ; SET UP TYPE TABLE
+       ADD     E,TYPTAB
+       JUMPGE  E,VUP           ; SKIP OVER IF DONE
+TYPUP1:        PUSH    P,C%0           ; PUSH SLOT FOR POSSIBLE TEMPLATE ATOM
+       HLRZ    A,1(E)          ; GET POSSIBLE ATOM SLOT
+       JUMPE   A,TYPUP2        ; JUMP IF NOT A TEMPLATE
+       ADD     A,ABOTN         ; GET ATOM
+       ADD     A,1(TB)
+       MOVE    A,-1(A)
+       MOVE    B,TYPVEC+1      ; GET TYPE VECTOR SLOT FOR LOOP TO SEE IF ITS THERE
+TYPUP3:        CAMN    A,1(B)          ; SKIP IF NOT EQUAL
+       JRST    TYPUP4          ; FOUND ONE
+       ADD     B,C%22          ; TO NEXT
+       JUMPL   B,TYPUP3
+       JRST    ERTYP1          ; ERROR NONE EXISTS
+TYPUP4:        HRRZ    C,(B)           ; GET SAT SLOT
+       CAIG    C,NUMSAT        ; MAKE SURE TYPE IS A TEMPLATE
+       JRST    ERTYP2          ; IF NOT COMPLAIN
+       HRLM    C,1(E)          ; SMASH IN NEW SAT
+       MOVE    B,1(B)          ; GET ATOM OF PRIMTYPE
+       MOVEM   B,(P)           ; PUSH  ONTO STACK
+TYPUP2:        MOVEI   D,0             ; INITIALIZE TYPE COUNT FOR LOOKUP LOOP
+       MOVE    B,TYPVEC+1      ; GET PTR FOR LOOP
+       HRRZ    A,1(E)          ; GET TYPE'S ATOM ID
+       ADD     A,ABOTN         ; GET ATOM
+       ADD     A,1(TB)
+       MOVE    A,-1(A)
+TYPUP5:        CAMN    A,1(B)          ; SKIP IF NOT EQUAL
+       JRST    TYPUP6          ; FOUND ONE
+       ADDI    D,1             ; INCREMENT TYPE-COUNT
+       ADD     B,C%22          ; POINT TO NEXT
+       JUMPL   B,TYPUP5
+       HRRM    D,1(E)          ; CLOBBER IN TYPE-NUMBER
+       PUSH    TP,$TATOM       ; PUSH ARGS FOR NEWTYPE
+       PUSH    TP,A
+       PUSH    TP,$TATOM
+       POP     P,B             ; GET BACK POSSIBLE PRIMTYPE ATOM
+       JUMPE   B,TYPUP7        ; JUMP IF NOT A TEMPLATE
+       PUSH    TP,B            ; PUSH ON PRIMTYPE
+TYPUP9:        SUB     E,1(TB)
+       PUSH    P,E             ; SAVE RELATAVIZED PTR TO TYPE-TABLE
+       MCALL   2,NEWTYPE
+       POP     P,E             ; RESTORE RELATAVIZED PTR
+       ADD     E,1(TB)         ; FIX IT UP
+TYPUP0:        ADD     E,C%22          ; INCREMENT E
+       JUMPL   E,TYPUP1
+       JRST    VUP
+TYPUP7:        HRRZ    B,(E)           ; FIND PRIMTYPE FROM SAT
+       MOVE    A,@STBL(B)
+       PUSH    TP,A
+       JRST    TYPUP9
+TYPUP6:        HRRM    D,1(E)          ; CLOBBER IN TYPE #
+       JRST    TYPUP0
+
+ERTYP1:        ERRUUO  EQUOTE CANT-FIND-TEMPLATE
+
+ERTYP2:        ERRUUO  EQUOTE TEMPLATE-TYPE-NAME-NOT-OF-TYPE-TEMPLATE
+
+VUP:   HRRZ    E,1(TB)         ; FIX UP SOME POINTERS
+       MOVEM   E,OGCSTP
+       ADDM    E,ABOTN
+       ADDM    E,TYPTAB
+
+
+; ROUTINE TO SWEEP THRU THE READ-IN IMAGE LOOKING FOR UVECTORS AND TEMPLATES.
+; WHILE SWEEPING IT FIXES UP THE DOPE WORDS APPROPRIATELY.
+
+       HRRZ    A,TYPTAB        ; GET TO TOP OF WORLD
+       SUBI    A,2             ; GET TO FIRST TYPE WORD OR DOPE-WORD OF FIRST OBJECT
+VUP1:  CAMG    A,OGCSTP        ; SKIP IF NOT DONE
+       JRST    VUP3
+       HLRZ    B,(A)           ; GET TYPE SLOT
+       TRNE    B,.VECT.        ; SKIP IF NOT A VECTOR
+       JRST    VUP2
+       SUBI    A,2             ; SKIP OVER PAIR
+       JRST    VUP1
+VUP2:  TRNE    B,400000        ; SKIP IF UVECTOR
+       JRST    VUP4
+       ANDI    B,TYPMSK        ; GET RID OF MONITORS
+       CAMG    B,NNPRI         ; SKIP IF NEWTYPE
+       JRST    VUP5
+       PUSHJ   P,GETNTP        ; GET THE NEW TYPE #
+       PUTYP   B,(A)           ; SMASH IT IT
+VUP5:  HLRZ    B,1(A)          ; SKIP OVER VECTOR
+       TRZ     B,400000        ; GET RID OF POSSIBLE MARK BIT
+       SUBI    A,(B)
+       JRST    VUP1            ; LOOP
+VUP4:  ANDI    B,TYPMSK        ; FLUSH MONITORS
+       CAMG    B,NNSAT         ; SKIP IF TEMPLATE
+       JRST    VUP5
+       PUSHJ   P,GETSAT        ; CONVERT TO NEW SAT
+       ADDI    B,.VECT.        ; MAJIC TO TURN ON BIT
+       PUTYP   B,(A)
+       JRST    VUP5
+
+
+VUP3:  PUSH    P,GCSBOT        ; SAVE CURRENT GCSBOT
+       MOVE    A,OGCSTP        ; SET UP NEW GCSBOT
+       MOVEM   A,GCSBOT
+       PUSH    P,GCSTOP
+       HRRZ    A,TYPTAB                ; SET UP NEW GCSTOP
+       MOVEM   A,GCSTOP
+       SETOM   GCDFLG
+       MOVE    A,[PUSHJ P,RDFIX]       ; INS FOR GCHACK
+       MOVEI   PVP,0           ; SAY MIGHT BE NON-ATOMS
+       PUSHJ   P,GCHK10
+       SETZM   GCDFLG
+       POP     P,GCSTOP        ; RESTORE GCSTOP
+       MOVE    A,1(TB)         ; GET A POINTER TO RETURNING VALUES
+       MOVE    B,A
+       HLRE    C,B
+       SUB     B,C
+       SETZM   (B)
+       SETZM   1(B)
+       POP     P,GCSBOT        ; RESTORE GCSBOT
+       MOVE    B,1(A)          ; GET PTR TO OBJECTS
+       MOVE    A,(A)
+       JRST    FINIS           ; EXIT
+
+; ERROR FOR INCORRECT GCREAD FILE
+
+ERDGC: ERRUUO  EQUOTE BAD-GC-READ-FILE
+
+; ROUTINE CALLED BY GCHACK TO UPDATE PTRS IN THE NEW CORE IMAGE
+
+RDFIX: PUSH    P,C             ; SAVE C
+       PUSH    P,B             ; SAVE PTR
+       EXCH    B,C
+       TLNE    C,UBIT          ; SKIP IF NOT UVECTOR
+       JRST    ELEFX           ; DON'T HACK TYPES IN UVECTOR
+       CAIN    B,TTYPEC
+       JRST    TYPCFX
+       CAIN    B,TTYPEW
+       JRST    TYPWFX
+       CAML    B,NNPRI
+       JRST    TYPGFX
+ELEFX: EXCH    B,A             ; EXCHANGE FOR SAT 
+       PUSHJ   P,SAT
+       EXCH    B,A             ; REFIX
+       CAIE    B,SLOCR         ; REL GLOC'S ARE STORED AS ATOMS
+       CAIN    B,SATOM
+       JRST    ATFX
+       CAIN    B,SCHSTR
+        JRST   STFX
+       CAIN    B,S1WORD                ; SEE IF PRIMTYPE WOR
+       JRST    RDLSTF          ; LEAVE IF IS
+STFXX: MOVE    0,GCSBOT        ; ADJUSTMENT
+       SUBI    0,FPAG+5
+       SKIPE   1(C)            ; DON'T CHANGE A PTR TO NIL
+       ADDM    0,1(C)          ; FIX UP
+RDLSTF:        TLNN    C,.LIST.        ; SEE IF PAIR
+       JRST    RDL1            ; EXIT
+       MOVE    0,GCSBOT        ; FIX UP
+       SUBI    0,FPAG+5
+       HRRZ    B,(C)           ; SEE IF POINTS TO NIL
+       SKIPN   B
+       JRST    RDL1
+       MOVE    B,C             ; GET ARG FOR RLISTQ
+       PUSHJ   P,RLISTQ
+       JRST    RDL1
+       ADDM    0,(C)
+RDL1:  POP     P,B             ; RESTORE B
+       POP     P,C
+       POPJ    P,
+
+; ROUTINE TO FIX UP PNAMES
+
+STFX:  TLZN    D,STATM
+        JRST   STFXX
+       HLLM    D,1(C)          ; PUT BACK WITH BIT OFF
+       ADD     D,ABOTN
+       ANDI    D,-1
+       HLRE    0,-1(D)         ; LENGTH OF ATOM
+       MOVNS   0
+       SUBI    0,3             ; VAL & OBLIST
+       IMULI   0,5             ; TO CHARS (SORT OF)
+       HRRZ    D,-1(D)
+       ADDI    D,2
+       PUSH    P,A
+       PUSH    P,B
+       LDB     A,[360600,,1(C)]        ; GET BYTE POS
+       IDIVI   A,7             ; TO CHAR POS
+       SKIPE   A
+        SUBI   A,5
+       HRRZ    B,(C)           ; STRING LENGTH
+       SUB     B,A             ; TO WORD BOUNDARY STRING
+       SUBI    0,(B)
+       IDIVI   0,5
+       ADD     D,0
+       POP     P,B
+       POP     P,A
+       HRRM    D,1(C)
+       JRST    RDLSTF
+
+; ROUTINE TO FIX UP POINTERS TO ATOMS
+
+ATFX:  SKIPGE  D
+       JRST    RDLSTF
+       ADD     D,ABOTN
+       MOVE    0,-1(D)         ; GET PTR TO ATOM
+       CAIE    B,SLOCR         ; IF REL LOCATIVE, MORE HAIR
+        JRST   ATFXAT
+       MOVE    B,0
+       PUSH    P,E
+       PUSH    P,D
+       PUSH    P,C
+       PUSH    P,B
+       PUSH    P,A
+       PUSHJ   P,IGLOC
+       SUB     B,GLOTOP+1
+       MOVE    0,B
+       POP     P,A
+       POP     P,B
+       POP     P,C
+       POP     P,D
+       POP     P,E
+ATFXAT:        MOVEM   0,1(C)          ; SMASH IT IN
+       JRST    RDLSTF          ; EXIT
+
+TYPCFX:        HRRZ    B,1(C)          ; GET TYPE
+       PUSHJ   P,GETNEW                ; GET TYPE IN THIS CORE IMAGE
+       HRRM    B,1(C)          ; CLOBBER IT IN
+       JRST    RDLSTF          ; CONTINUE FIXUP
+
+TYPWFX:        HLRZ    B,1(C)          ; GET TYPE
+       PUSHJ   P,GETNEW        ; GET TYPE IN THIS CORE IMAGE
+       HRLM    B,1(C)          ; SMASH IT IN
+       JRST    ELEFX
+
+TYPGFX:        PUSH    P,D
+       PUSHJ   P,GETNTP                ; GET TYPE IN THIS CORE IMAGE
+       POP     P,D
+       PUTYP   B,(C)
+       JRST    ELEFX
+
+; HERE TO HANDLE AN EOF IN GC-READ.  IT USES OPTIONAL SECOND ARG IF SUPPLIED AS
+; EOF HANDLER ELSE USES CHANNELS.
+
+EOFGC: MOVE    B,1(AB)         ; GET CHANNEL INTO B
+       CAML    AB,C%M20        ; [-2,,0] ; SKIP IF EOF ROUTINE IS SUPPLIED
+       JRST    MYCLOS          ; USE CHANNELS
+       PUSH    TP,2(AB)
+       PUSH    TP,3(AB)
+       JRST    CLOSIT
+MYCLOS:        PUSH    TP,EOFCND-1(B)
+       PUSH    TP,EOFCND(B)
+CLOSIT:        PUSH    TP,$TCHAN
+       PUSH    TP,B
+       MCALL   1,FCLOSE                ; CLOSE CHANNEL
+       MCALL   1,EVAL                  ; EVAL HIS EOF HANDLER
+       JRST    FINIS
+
+; ROUTINE TO SUPPLY THE TYPE NUMBER FOR A NEWTYPE
+
+GETNEW:        CAMG    B,NNPRI         ;NEWTYPE
+       POPJ    P,
+GETNTP:        MOVE    D,TYPTAB        ; GET AOBJN POINTER TO TYPE-TABLE
+GETNT1:        HLRZ    E,(D)           ; GET TYPE #
+       CAIN    E,(B)           ; SKIP IF NOT EQUAL TO GOAL
+       JRST    GOTTYP          ; FOUND IT
+       ADD     D,C%22          ; POINT TO NEXT
+       JUMPL   D,GETNT1
+       SKIPA                   ; KEEP TYPE SAME
+GOTTYP:        HRRZ    B,1(D)          ; GET NEW TYPE #
+       POPJ    P,
+
+; ROUTINE TO SUPPLY THE SAT TO A TEMPLATE HACKER
+
+GETSAT:        MOVE    D,TYPTAB        ; GET AOBJN PTR TO TYPE TABLE
+GETSA1:        HRRZ    E,(D)           ; GET OBJECT
+       CAIN    E,(B)           ; SKIP IF NOT EQUAL TO GOAL
+       JRST    GOTSAT          ; FOUND IT
+       ADD     D,C%22
+       JUMPL   D,GETSA1
+       FATAL GC-DUMP -- TYPE FIXUP FAILURE
+GOTSAT:        HLRZ    B,1(D)          ; GET NEW SAT
+       POPJ    P,
+
+
+; A ROUTINE TO DISTINGUISH BETWEEN A DEFERRED AND A LIST POINTER
+RLISTQ:        PUSH    P,A
+       GETYP   A,(B)           ; GET TYPE
+       PUSHJ   P,SAT           ; GET SAT
+       CAIG    A,NUMSAT        ; NOT DEFERRED IF TEMPLATE
+       SKIPL   MKTBS(A)
+       AOS     -1(P)           ; SKIP IF NOT DEFFERED
+       POP     P,A
+       POPJ    P,              ; EXIT
+
+\f
+.GLOBAL FLIST
+
+MFUNCTION BLOATSTAT,SUBR,[BLOAT-STAT]
+
+ENTRY
+
+       JUMPGE  AB,GETUVC       ; SEE IF THERE IS AN ARGUMENT
+       GETYP   A,(AB)
+       CAIE    A,TUVEC         ; SEE IF THE ARGUMENT IS A UVECTOR
+       JRST    WTYP1           ; IF NOT COMPLAIN
+       HLRE    0,1(AB)
+       MOVNS   0
+       CAIE    0,STATNO+STATGC ; SEE IF UVECTOR IS RIGHT LENGTH
+       JRST    WTYP1
+       CAMGE   AB,C%M20        ; [-2,,0] ; SEE IF THERE ARE TOO MANY ARGUMENTS
+       JRST    TMA
+       MOVE    A,(AB)          ; GET THE UVECTOR
+       MOVE    B,1(AB)
+       JRST    SETUV           ; CONTINUE
+GETUVC:        MOVEI   A,STATNO+STATGC ; CREATE A UVECTOR
+       PUSHJ   P,IBLOCK
+SETUV: PUSH    P,A             ; SAVE UVECTOR
+       PUSH    P,B
+       MOVE    0,NOWFRE        ; COMPUTE FREE STORAGE USED SINCE LAST BLOAT-STAT
+       SUB     0,RFRETP
+       ADD     0,GCSTOP
+       MOVEM   0,CURFRE
+       PUSHJ   P,GCSET         ; FIX UP BLOAT-STAT PARAMETERS
+       HLRE    0,TP            ; COMPUTE STACK SPACE USED UP
+       ADD     0,NOWTP
+       SUBI    0,PDLBUF
+       MOVEM   0,CURTP
+       MOVE    B,IMQUOTE THIS-PROCESS
+       PUSHJ   P,ILOC
+       HRRZS   B
+       MOVE    PVP,PVSTOR+1
+       HRRZ    C,TPBASE+1(PVP) ; CALCULATE # OF ATOM SLOTS
+       MOVE    0,B
+       HRRZ    D,SPBASE+1(PVP)         ; COMPUTE CURRENT # OF BINDINGS
+       SUB     0,D
+       IDIVI   0,6
+       MOVEM   0,CURLVL
+       SUB     B,C             ; TOTAL WORDS ATOM STORAGE
+       IDIVI   B,6             ; COMPUTE # OF SLOTS
+       MOVEM   B,NOWLVL
+       HRRZ    A,GLOBASE+1     ; COMPUTE TOTAL # OF GLOBAL SLOTS
+       HLRE    0,GLOBASE+1
+       SUB     A,0             ; POINT TO DOPE WORD
+       HLRZ    B,1(A)
+       ASH     B,-2            ; # OF GVAL SLOTS
+       MOVEM   B,NOWGVL
+       HRRZ    A,GLOTOP+1      ; COMPUTE # OF GVAL SLOTS IN USE
+       HRRZ    0,GLOBSP+1
+       SUB     A,0
+       ASH     A,-2            ; NEGATIVE # OF SLOTS USED
+       MOVEM   A,CURGVL
+       HRRZ    A,TYPBOT+1      ; GET LENGTH OF TYPE VECTOR
+       HLRE    0,TYPBOT+1
+       SUB     A,0
+       HLRZ    B,1(A)          ; # OF WORDS IN TYPE-VECTOR
+       IDIVI   B,2             ; CONVERT TO # OF TYPES
+       MOVEM   B,NOWTYP
+       HLRE    0,TYPVEC+1      ; LENGTH OF VISABLE TYPE-VECTOR
+       MOVNS   0
+       IDIVI   0,2             ; GET # OF TYPES
+       MOVEM   0,CURTYP
+       MOVE    0,CODTOP        ; GET LENGTH OF STATIONARY IMPURE STORAGE
+       MOVEM   0,NOWSTO
+       SETZB   B,D             ; ZERO OUT MAXIMUM
+       HRRZ    C,FLIST
+LOOPC: HLRZ    0,(C)           ; GET BLK LENGTH
+       ADD     D,0             ; ADD # OF WORDS IN BLOCK
+       CAMGE   B,0             ; SEE IF NEW MAXIMUM
+       MOVE    B,0
+       HRRZ    C,(C)           ; POINT TO NEXT BLOCK
+       JUMPN   C,LOOPC         ; REPEAT
+       MOVEM   D,CURSTO
+       MOVEM   B,CURMAX
+       HLRE    0,P             ; GET AMOUNT OF ROOM LEFT ON P
+       ADD     0,NOWP
+       SUBI    0,PDLBUF
+       MOVEM   0,CURP
+       MOVSI   C,BSTGC         ; SET UP BLT FOR GC FIGURES
+       HRRZ    B,(P)           ; RESTORE B
+       HRR     C,B
+       BLT     C,(B)STATGC-1
+       HRLI    C,BSTAT         ; MODIFY BLT FOR STATS
+       HRRI    C,STATGC(B)
+       BLT     C,(B)STATGC+STATNO-1
+       MOVEI   0,TFIX+.VECT.
+       HRLM    0,(B)STATNO+STATGC      ; MOVE IN UTYPE
+       POP     P,B
+       POP     P,A             ; RESTORE TYPE-WORD
+       JRST    FINIS
+
+GCRSET:        SETZM   GCNO            ; CALL FROM INIT, ZAP ALL 1ST
+       MOVE    0,[GCNO,,GCNO+1]
+       BLT     0,GCCALL
+       JRST    GCSET
+
+
+
+\f
+.GLOBAL PGFIND,PGGIVE,PGTAKE,PGINT
+
+; USER GARBAGE COLLECTOR INTERFACE
+.GLOBAL ILVAL
+
+MFUNCTION GC,SUBR
+       ENTRY
+
+       JUMPGE  AB,GC1
+       CAMGE   AB,C%M60        ; [-6,,0]
+       JRST    TMA
+       PUSHJ   P,GETFIX        ; GET FREEE MIN IF GIVEN
+       SKIPE   A               ; SKIP FOR 0 ARGUMENT
+       MOVEM   A,FREMIN
+GC1:   PUSHJ   P,COMPRM        ; GET CURRENT USED CORE
+       PUSH    P,A
+       CAML    AB,C%M40        ; [-4,,0] ; SEE IF 3RD ARG
+       JRST    GC5
+       GETYP   A,4(AB)         ; MAKE SURE A FIX
+       CAIE    A,TFIX
+       JRST    WTYP            ; ARG WRONG TYPE
+       MOVE    A,5(AB)
+       MOVEM   A,RNUMSP
+       MOVEM   A,NUMSWP
+GC5:   CAML    AB,C%M20        ; [-2,,0] ; SEE IF SECOND ARG
+       JRST    GC3
+       GETYP   A,2(AB)         ; SEE IF NONFALSE
+       CAIE    A,TFALSE        ; SKIP IF FALSE
+       JRST    HAIRGC          ; CAUSE A HAIRY GC
+GC3:   MOVSI   A,TATOM         ; CHECK TO SEE IF INTERRUPT FLAG IS ON
+       MOVE    B,IMQUOTE AGC-FLAG
+       PUSHJ   P,ILVAL
+       CAMN    A,$TUNBOUND     ; SKIP IF NOT UNBOUND
+       JRST    GC2
+       SKIPE   GCHPN           ; SKIP IF GCHAPPEN IS 0
+       JRST    FALRTN          ; JUMP TO RETURN FALSE
+GC2:   MOVE    C,[9.,,0]
+       PUSHJ   P,AGC           ; COLLECT THAT TRASH
+       PUSHJ   P,COMPRM        ; HOW MUCH ROOM NOW?
+       POP     P,B             ; RETURN AMOUNT
+       SUB     B,A
+       MOVSI   A,TFIX
+       JRST    FINIS
+HAIRGC:        MOVE    B,3(AB)
+       CAIN    A,TFIX          ; IF FIX THEN CLOBBER NGCS
+       MOVEM   B,NGCS
+       MOVEI   A,1             ; FORCE VALUE FLUSHING PHASE TO OCCUR
+       MOVEM   A,GCHAIR
+       JRST    GC2             ; HAIRY GC OCCORS NO MATTER WHAT
+FALRTN:        MOVE    A,$TFALSE
+       MOVEI   B,0             ; RETURN A FALSE-- FOR GC WHICH DIDN'T OCCOR
+       JRST    FINIS
+
+
+COMPRM:        MOVE    A,GCSTOP        ; USED SPACE
+       SUB     A,GCSBOT
+       POPJ    P,
+
+\f
+MFUNCTION GCDMON,SUBR,[GC-MON]
+
+       ENTRY
+
+       MOVEI   E,GCMONF
+
+FLGSET:        MOVE    C,(E)           ; GET CURRENT VALUE
+       JUMPGE  AB,RETFLG       ; RET CURRENT
+       CAMGE   AB,C%M20        ; [-3,,]
+        JRST   TMA
+       GETYP   0,(AB)
+       SETZM   (E)
+       CAIN    0,TFALSE
+       SETOM   (E)
+       SKIPL   E
+       SETCMM  (E)
+
+RETFLG:        SKIPL   E
+       SETCMM  C
+       JUMPL   C,NOFLG
+       MOVSI   A,TATOM
+       MOVE    B,IMQUOTE T
+       JRST    FINIS
+
+NOFLG: MOVEI   B,0
+       MOVSI   A,TFALSE
+       JRST    FINIS
+
+.GLOBAL EVATYP,APLTYP,PRNTYP
+
+\fMFUNCTION BLOAT,SUBR
+       ENTRY
+
+       PUSHJ   P,SQKIL
+       MOVEI   C,0             ; FLAG TO SAY WHETHER NEED A GC
+       MOVSI   E,-NBLO         ; AOBJN TO BLOATER TABLE
+
+BLOAT2:        JUMPGE  AB,BLOAT1       ; ALL DONE?
+       PUSHJ   P,NXTFIX        ; GET NEXT BLOAT PARAM
+       SKIPE   A
+       PUSHJ   P,@BLOATER(E)   ; DISPATCH
+       AOBJN   E,BLOAT2        ; COUNT PARAMS SET
+
+       JUMPL   AB,TMA          ; ANY LEFT...ERROR
+BLOAT1:        JUMPE   C,BLOATD        ; DONE, NO GC NEEDED
+       MOVE    C,E             ; MOVE IN INDICATOR
+       HRLI    C,1             ; INDICATE THAT IT COMES FROM BLOAT
+       SETOM   INBLOT
+       PUSHJ   P,AGC           ; DO ONE
+       SKIPE   A,TPBINC        ; SMASH POINNTERS
+       MOVE    PVP,PVSTOR+1
+       ADDM    A,TPBASE+1(PVP)
+       SKIPE   A,GLBINC        ; GLOBAL SP
+       ADDM    A,GLOBASE+1
+       SKIPE   A,TYPINC
+       ADDM    A,TYPBOT+1
+       SETZM   TPBINC          ; RESET PARAMS
+       SETZM   GLBINC
+       SETZM   TYPINC
+
+BLOATD:        SKIPN   A,GETNUM        ; SKIP IF FREE STORAGE REQUEST IN EFFECT
+       JRST    BLTFN
+       ADD     A,FRETOP        ; ADD FRETOP
+       ADDI    A,1777          ; ONE BLOCK FOR MARK PDL AND ROUND
+       ANDCMI  A,1777          ; TO PAGE BOUNDRY
+       CAML    A,PURBOT        ; SKIP IF POSSIBLE TO WIN
+       JRST    BLFAGC
+       ASH     A,-10.          ; TO PAGES
+       PUSHJ   P,P.CORE        ; GRET THE CORE
+       JRST    BLFAGC          ; LOSE LOSE LOSE
+       MOVE    A,FRETOP        ; CALCULATE NEW PARAMETERS
+       MOVEM   A,RFRETP
+       MOVEM   A,CORTOP
+       MOVE    B,GCSTOP
+       SETZM   1(B)
+       HRLI    B,1(B)
+       HRRI    B,2(B)
+       BLT     B,-1(A) ; ZERO CORE
+BLTFN: SETZM   GETNUM
+       MOVE    B,FRETOP
+       SUB     B,GCSTOP
+       MOVSI   A,TFIX          ; RETURN CORE FOUND
+       JRST    FINIS
+BLFAGC:        MOVN    A,FREMIN
+       ADDM    A,GETNUM                ; FIX UP SO BLOATS CORRECTLY
+       MOVE    C,C%11          ; INDICATOR FOR AGC
+       PUSHJ   P,AGC           ; GARBAGE COLLECT
+       JRST    BLTFN           ; EXIT
+
+; TABLE OF BLOAT ROUTINES
+
+BLOATER:
+       MAINB
+       TPBLO
+       LOBLO
+       GLBLO
+       TYBLO
+       STBLO
+       PBLO
+       SFREM
+       SLVL
+       SGVL
+       STYP
+       SSTO
+       PUMIN
+       PMUNG
+       TPMUNG
+       NBLO==.-BLOATER
+
+; BLOAT MAIN STORAGE AREA
+
+MAINB: SETZM   GETNUM
+       MOVE    D,FRETOP        ; COMPUTE CURRENT ROOM
+       SUB     D,PARTOP
+       CAMGE   A,D             ; NEED MORE?
+       POPJ    P,              ; NO, LEAVE
+       SUB     A,D
+       MOVEM   A,GETNUM                ; SAVE
+       POPJ    P,
+
+; BLOAT TP STACK (AT TOP)
+
+TPBLO: HLRE    D,TP            ; GET -SIZE
+       MOVNS   B,D
+       ADDI    D,1(TP)         ; POINT TO DOPE (ALMOST)
+       CAME    D,TPGROW        ; BLOWN?
+       ADDI    D,PDLBUF        ; POINT TO REAL DOPE WORD
+       SUB     A,B             ; SKIP IF GROWTH NEEDED
+       JUMPLE  A,CPOPJ
+       ADDI    A,63.
+       ASH     A,-6            ; CONVERT TO 64 WD BLOCKS
+       CAILE   A,377
+       JRST    OUTRNG
+       DPB     A,[111100,,-1(D)]       ; SMASH SPECS IN
+       AOJA    C,CPOPJ
+
+; BLOAT TOP LEVEL LOCALS
+
+LOBLO: HLRE    D,TP            ; GET -SIZE
+       MOVNS   B,D
+       ADDI    D,1(TP)         ; POINT TO DOPE (ALMOST)
+       CAME    D,TPGROW        ; BLOWN?
+       ADDI    D,PDLBUF        ; POINT TO REAL DOPE WORD
+       CAMG    A,B             ; SKIP IF GROWTH NEEDED
+       IMULI   A,6             ; 6 WORDS PER BINDING
+       MOVE    PVP,PVSTOR+1
+       HRRZ    0,TPBASE+1(PVP)
+       HRRZ    B,SPBASE+1(PVP) ; ROOM AVAIL TO E
+       SUB     B,0
+       SUBI    A,(B)           ; HOW MUCH MORE?
+       JUMPLE  A,CPOPJ         ; NONE NEEDED
+       MOVEI   B,TPBINC
+       PUSHJ   P,NUMADJ
+       DPB     A,[1100,,-1(D)] ; SMASH
+       AOJA    C,CPOPJ
+
+; GLOBAL SLOT GROWER
+
+GLBLO: ASH     A,2             ; 4 WORDS PER VAR
+       MOVE    D,GLOBASE+1     ; CURRENT LIMITS
+       HRRZ    B,GLOBSP+1
+       SUBI    B,(D)
+       SUBI    A,(B)           ; NEW AMOUNT NEEDED
+       JUMPLE  A,CPOPJ
+       MOVEI   B,GLBINC        ; WHERE TO KEEP UPDATE
+       PUSHJ   P,NUMADJ        ; FIX NUMBER
+       HLRE    0,D
+       SUB     D,0             ; POINT TO DOPE
+       DPB     A,[1100,,(D)]   ; AND SMASH
+       AOJA    C,CPOPJ
+
+; HERE TO GROW TYPE VECTOR (AND FRIENDS)
+
+TYBLO: ASH     A,1             ; TWO WORD PER TYPE
+       HRRZ    B,TYPVEC+1      ; FIND CURRENT ROOM
+       MOVE    D,TYPBOT+1
+       SUBI    B,(D)
+       SUBI    A,(B)           ; EXTRA NEEDED TO A
+       JUMPLE  A,CPOPJ         ; NONE NEEDED, LEAVE
+       MOVEI   B,TYPINC        ; WHERE TO STASH SPEC
+       PUSHJ   P,NUMADJ        ; FIX NUMBER
+       HLRE    0,D             ; POINT TO DOPE
+       SUB     D,0
+       DPB     A,[1100,,(D)]
+       SKIPE   D,EVATYP+1      ; GROW AUX TYPE VECS IF NEEDED
+       PUSHJ   P,SGROW1
+       SKIPE   D,APLTYP+1
+       PUSHJ   P,SGROW1
+       SKIPE   D,PRNTYP+1
+       PUSHJ   P,SGROW1
+       AOJA    C,CPOPJ
+
+; HERE TO CREATE STORAGE SPACE
+
+STBLO: MOVE    D,GCSBOT        ; HOW MUCH NOW HERE
+       SUB     D,CODTOP
+       SUBI    A,(D)           ; MORE NEEDED?
+       JUMPLE  A,CPOPJ
+       MOVEM   A,PARNEW        ; FORCE PAIR SPACE TO MOVE ON OUT
+       AOJA    C,CPOPJ
+
+; BLOAT P STACK
+
+PBLO:  HLRE    D,P
+       MOVNS   B,D
+       SUBI    D,5             ; FUDGE FOR THIS CALL
+       SUBI    A,(D)
+       JUMPLE  A,CPOPJ
+       ADDI    B,1(P)          ; POINT TO DOPE
+       CAME    B,PGROW         ; BLOWN?
+       ADDI    B,PDLBUF        ; NOPE, POIN TO REAL D.W.
+       ADDI    A,63.
+       ASH     A,-6            ; TO 64 WRD BLOCKS
+       CAILE   A,377           ; IN RANGE?
+       JRST    OUTRNG
+       DPB     A,[111100,,-1(B)]
+       AOJA    C,CPOPJ
+                       
+; SET FREMIN
+
+SFREM: SKIPE   A               ; DON'T ZERO EMPTY PARAMETER
+       MOVEM   A,FREMIN
+       POPJ    P,
+
+; SET LVAL INCREMENT
+
+SLVL:  IMULI   A,6             ; CALCULATE AMOUNT TO GROW B
+       MOVEI   B,LVLINC
+       PUSHJ   P,NUMADJ
+       MOVEM   A,LVLINC
+       POPJ P,
+
+; SET GVAL INCREMENT
+
+SGVL:  IMULI   A,4.            ; # OF SLOTS
+       MOVEI   B,GVLINC
+       PUSHJ   P,NUMADJ
+       MOVEM   A,GVLINC
+       POPJ    P,
+
+; SET TYPE INCREMENT
+
+STYP:  IMULI   A,2             ; CALCULATE NUMBER OF GROW BLOCKS NEEDED
+       MOVEI   B,TYPIC
+       PUSHJ   P,NUMADJ
+       MOVEM   A,TYPIC
+       POPJ    P,
+
+; SET STORAGE INCREMENT
+
+SSTO:  IDIVI   A,2000          ; # OF BLOCKS
+       CAIE    B,0             ; REMAINDER?
+       ADDI    A,1
+       IMULI   A,2000          ; CONVERT BACK TO WORDS
+       MOVEM   A,STORIC
+       POPJ    P,
+; HERE FOR MINIMUM PURE SPACE
+
+PUMIN: ADDI    A,1777
+       ANDCMI  A,1777          ; TO PAGE BOUNDRY
+       MOVEM   A,PURMIN
+       POPJ    P,
+
+; HERE TO ADJUST PSTACK PARAMETERS IN GC
+
+PMUNG: ADDI    A,777           ; TO NEAREST 1000 WORD BOUNDRY
+       ANDCMI  A,777
+       MOVEM   A,PGOOD         ; PGOOD
+       ASH     A,2             ; PMAX IS 4*PGOOD
+       MOVEM   A,PMAX
+       ASH     A,-4            ; PMIN IS .25*PGOOD
+       MOVEM   A,PMIN
+
+; HERE TO ADJUST GC TPSTACK PARAMS
+
+TPMUNG:        ADDI    A,777
+       ANDCMI  A,777           ; TO NEAREST 1000 WORD BOUNDRY
+       MOVEM   A,TPGOOD
+       ASH     A,2             ; TPMAX= 4*TPGOOD
+       MOVEM   A,TPMAX
+       ASH     A,-4            ; TPMIN= .25*TPGOOD
+       MOVEM   A,TPMIN
+
+
+; GET NEXT (FIX) ARG
+
+NXTFIX:        PUSHJ   P,GETFIX
+       ADD     AB,C%22
+       POPJ    P,
+
+; ROUTINE TO GET POS FIXED ARG
+
+GETFIX:        GETYP   A,(AB)
+       CAIE    A,TFIX
+       JRST    WRONGT
+       SKIPGE  A,1(AB)
+       JRST    BADNUM
+       POPJ    P,
+
+
+; GET NUMBERS FIXED UP FOR GROWTH FIELDS
+
+NUMADJ:        ADDI    A,77            ; ROUND UP
+       ANDCMI  A,77            ; KILL CRAP
+       MOVE    0,A
+       MOVNS   A               ; COMPUTE ADD FACTOR FOR SPEC. POINTER UPDATE
+       HRLI    A,-1(A)
+       MOVEM   A,(B)           ; AND STASH IT
+       MOVE    A,0
+       ASH     A,-6            ; TO 64 WD BLOCKS
+       CAILE   A,377           ; CHECK FIT
+       JRST    OUTRNG
+       POPJ    P,
+
+; DO SYMPATHETIC GROWTHS
+
+SGROW1:        HLRE    0,D
+       SUB     D,0
+       DPB     A,[111100,,(D)]
+       POPJ    P,
+
+\f;FUNCTION TO CONSTRUCT A LIST
+
+MFUNCTION CONS,SUBR
+
+       ENTRY   2
+       GETYP   A,2(AB)         ;GET TYPE OF 2ND ARG
+       CAIE    A,TLIST         ;LIST?
+       JRST    WTYP2           ;NO , COMPLAIN
+       MOVE    C,(AB)          ; GET THING TO CONS IN
+       MOVE    D,1(AB)
+       HRRZ    E,3(AB)         ; AND LIST
+       PUSHJ   P,ICONS         ; INTERNAL CONS
+       JRST    FINIS
+
+; COMPILER CALL TO CONS
+
+C1CONS:        PUSHJ   P,ICELL2
+       JRST    ICONS2
+ICONS4:        HRRI    C,(E)
+ICONS3:        MOVEM   C,(B)           ; AND STORE
+       MOVEM   D,1(B)
+TLPOPJ:        MOVSI   A,TLIST
+       POPJ    P,
+
+; INTERNAL CONS--ICONS;  C,D VALUE, E CDR
+
+; RELATIVIZE RETURN ADDRESS HERE--MUST BE DIFFERENT FROM ICONS, SINCE
+; ICONS IS CALLED FROM INTERPRETER ENTRIES WHICH ARE THEMSELVES PUSHJ'ED
+; TO:  DOING SUBM M,(P) ANYWHERE IN ICONS IS FATAL IF A GC OCCURS.
+
+CICONS:        SUBM    M,(P)
+       PUSHJ   P,ICONS
+       JRST    MPOPJ
+
+; INTERNAL CONS TO NIL--INCONS
+
+INCONS:        MOVEI   E,0
+
+ICONS: GETYP   A,C             ; CHECK TYPE OF VAL
+       PUSHJ   P,NWORDT        ; # OF WORDS
+       SOJN    A,ICONS1        ; JUMP IF DEFERMENT NEEDED
+       PUSHJ   P,ICELL2        ; NO DEFER, GET 2 WORDS FROM PAIR SPACE
+       JRST    ICNS2A          ; NO CORE, GO GC (SPECIAL PLACE, NOTICE)
+       JRST    ICONS4
+
+; HERE IF CONSING DEFERRED
+
+ICONS1:        MOVEI   A,4             ; NEED 4 WORDS
+       PUSHJ   P,ICELL         ; GO GET 'EM
+       JRST    ICNS2A          ; NOT THERE, GC (SAME PLACE AS FOR ICONS)
+       HRLI    E,TDEFER        ; CDR AND DEFER
+       MOVEM   E,(B)           ; STORE
+       MOVEI   E,2(B)          ; POINT E TO VAL CELL
+       HRRZM   E,1(B)
+       MOVEM   C,(E)           ; STORE VALUE
+       MOVEM   D,1(E)
+       JRST    TLPOPJ
+
+
+
+; HERE TO GC ON A CONS
+
+; HERE FROM C1CONS
+ICONS2:        SUBM    M,(P)
+       PUSHJ   P,ICONSG
+       SUBM    M,(P)
+       JRST    C1CONS
+
+; HERE FROM ICONS (THUS CICONS, INDIRECTLY), ICONS1
+ICNS2A:        PUSHJ   P,ICONSG
+       JRST    ICONS
+
+; REALLY DO GC
+ICONSG:        PUSH    TP,C            ; SAVE VAL
+       PUSH    TP,D
+       PUSH    TP,$TLIST
+       PUSH    TP,E            ; SAVE VITAL STUFF
+       ADDM    A,GETNUM        ; AMOUNT NEEDED
+       MOVE    C,[3,,1]        ; INDICATOR FOR AGC
+       PUSHJ   P,INQAGC                ; ATTEMPT TO WIN
+       MOVE    D,-2(TP)        ; RESTORE VOLATILE STUFF
+       MOVE    C,-3(TP)
+       MOVE    E,(TP)
+       SUB     TP,C%44         ; [4,,4]
+       POPJ    P,              ; BACK TO DRAWING BOARD
+
+; SUBROUTINE TO ALLOCATE WORDS IN PAIR SPACE.  CALLS AGC IF NEEDED
+
+CELL2: MOVEI   A,2             ; USUAL CASE
+CELL:  PUSHJ   P,ICELL         ; INTERNAL
+       JRST    .+2             ; LOSER
+       POPJ    P,
+
+       ADDM    A,GETNUM        ; AMOUNT REQUIRED
+       PUSH    P,A             ; PREVENT AGC DESTRUCTION
+       MOVE    C,[3,,1]        ; INDICATOR FOR AGC
+       PUSHJ   P,INQAGC
+       POP     P,A
+       JRST    CELL            ; AND TRY AGAIN
+
+; INTERNAL CELL GETTER, SKIPS IF ROO EXISTS, ELSE DOESN'T
+
+ICELL2:        MOVEI   A,2             ; MOST LIKELY CAE
+ICELL: SKIPE   B,RCL
+       JRST    ICELRC          ;SEE IF WE CAN RE-USE A RECYCLE CELL
+       MOVE    B,PARTOP        ; GET TOP OF PAIRS
+       ADDI    B,(A)           ; BUMP
+       CAMLE   B,FRETOP        ; SKIP IF OK.
+       JRST    VECTRY          ; LOSE
+       EXCH    B,PARTOP        ; SETUP NEW PARTOP AND RETURN POINTER
+       ADDM    A,USEFRE
+       JRST    CPOPJ1          ; SKIP RETURN
+
+; TRY RECYCLING USING A VECTOR FROM RCLV
+
+VECTRY:        SKIPN   B,RCLV          ; SKIP IF VECTOR EXISTS
+       POPJ    P,
+       PUSH    P,C
+       PUSH    P,A
+       MOVEI   C,RCLV
+VECTR1:        HLRZ    A,(B)           ; GET LENGTH
+       SUB     A,(P)
+       JUMPL   A,NXTVEC        ; DOESN'T SATISFY TRY AGAIN
+       CAIN    A,1             ; MAKE SURE NOT LEFT WITH A SINGLE SLOT
+       JRST    NXTVEC
+       JUMPN   A,SOML          ; SOME ARE LEFT
+       HRRZ    A,(B)
+       HRRM    A,(C)
+       HLRZ    A,(B)
+       SETZM   (B)
+       SETZM   -1(B)           ; CLEAR DOPE WORDS
+       SUBI    B,-1(A)
+       POP     P,A             ; CLEAR STACK
+       POP     P,C
+       JRST    CPOPJ1
+SOML:  HRLM    A,(B)           ; SMASH AMOUNT LEFT
+       SUBI    B,-1(A)         ; GET TO BEGINNING
+       SUB     B,(P) 
+       POP     P,A
+       POP     P,C
+       JRST    CPOPJ1
+NXTVEC:        MOVEI   C,(B)
+       HRRZ    B,(B)           ; GET NEXT
+       JUMPN   B,VECTR1
+       POP     P,A
+       POP     P,C
+       POPJ    P,
+       
+ICELRC:        CAIE    A,2
+       JRST    ICELL+2         ;IF HE DOESNT WANT TWO, USE OLD METHOD
+       PUSH    P,A
+       MOVE    A,(B)
+       HRRZM   A,RCL
+       POP     P,A
+       SETZM   (B)             ;GIVE HIM A CLEAN RECYCLED CELL
+       SETZM   1(B)
+       JRST    CPOPJ1          ;THAT IT
+
+
+\f;FUNCTION TO BUILD A LIST OF MANY ELEMENTS
+
+IMFUNCTION LIST,SUBR
+       ENTRY
+
+       PUSH    P,$TLIST
+LIST12:        HLRE    A,AB            ;GET -NUM OF ARGS
+       PUSH    TP,$TAB
+       PUSH    TP,AB
+       MOVNS   A               ;MAKE IT +
+       JUMPE   A,LISTN         ;JUMP IF 0
+       SKIPE   RCL             ;SEE IF WE WANT TO DO ONE AT A TIME
+       JRST    LST12R          ;TO GET RECYCLED CELLS
+       PUSHJ   P,CELL          ;GET NUMBER OF CELLS
+       PUSH    TP,(P)  ;SAVE IT
+       PUSH    TP,B
+       SUB     P,C%11  
+       LSH     A,-1            ;NUMBER OF REAL LIST ELEMENTS
+
+CHAINL:        ADDI    B,2             ;LOOP TO CHAIN ELEMENTS
+       HRRZM   B,-2(B)         ;CHAIN LAST ONE TO NEXT ONE
+       SOJG    A,.-2           ;LOOP TIL ALL DONE
+       CLEARM  B,-2(B)         ;SET THE  LAST CDR TO NIL
+
+; NOW LOBEER THE DATA IN TO THE LIST
+
+       MOVE    D,AB            ; COPY OF ARG POINTER
+       MOVE    B,(TP)          ;RESTORE LIS POINTER
+LISTLP:        GETYP   A,(D)           ;GET TYPE
+       PUSHJ   P,NWORDT        ;GET NUMBER OF WORDS
+       SOJN    A,LDEFER        ;NEED TO DEFER POINTER
+       GETYP   A,(D)           ;NOW CLOBBER ELEMENTS
+       HRLM    A,(B)
+       MOVE    A,1(D)          ;AND VALUE..
+       MOVEM   A,1(B)
+LISTL2:        HRRZ    B,(B)           ;REST B
+       ADD     D,C%22          ;STEP ARGS
+       JUMPL   D,LISTLP
+
+       POP     TP,B
+       POP     TP,A
+       SUB     TP,C%22         ; CLEANUP STACK
+       JRST    FINIS
+
+
+LST12R:        ASH     A,-1            ;ONE AT A TIME TO GET RECYCLED CELLS
+       JUMPE   A,LISTN
+       PUSH    P,A             ;SAVE COUNT ON STACK
+       SETZM   E
+       SETZB   C,D
+       PUSHJ   P,ICONS
+       MOVE    E,B             ;LOOP AND CHAIN TOGETHER
+       SOSLE   (P)
+       JRST    .-4
+       PUSH    TP,-1(P)        ;PUSH ON THE TYPE WE WANT
+       PUSH    TP,B
+       SUB     P,C%22          ;CLEAN UP AFTER OURSELVES
+       JRST    LISTLP-2        ;AND REJOIN MAIN STREAM
+
+
+; MAKE A DEFERRED POINTER
+
+LDEFER:        PUSH    TP,$TLIST       ;SAVE CURRENT POINTER
+       PUSH    TP,B
+       MOVEM   D,1(TB)         ; SAVE ARG HACKER
+       PUSHJ   P,CELL2
+       MOVE    D,1(TB)
+       GETYPF  A,(D)           ;GET FULL DATA
+       MOVE    C,1(D)
+       MOVEM   A,(B)
+       MOVEM   C,1(B)
+       MOVE    C,(TP)          ;RESTORE LIST POINTER
+       MOVEM   B,1(C)          ;AND MAKE THIS BE THE VALUE
+       MOVSI   A,TDEFER
+       HLLM    A,(C)           ;AND STORE IT
+       MOVE    B,C
+       SUB     TP,C%22
+       JRST    LISTL2
+
+LISTN: MOVEI   B,0
+       POP     P,A
+       JRST    FINIS
+
+; BUILD A FORM
+
+IMFUNCTION FORM,SUBR
+
+       ENTRY
+
+       PUSH    P,$TFORM
+       JRST    LIST12
+
+\f; COMPILERS CALLS TO FORM AND LIST A/ COUNT ELEMENTS ON STACK
+
+IILIST:        SUBM    M,(P)
+       PUSHJ   P,IILST
+       MOVSI   A,TLIST
+       JRST    MPOPJ
+
+IIFORM:        SUBM    M,(P)
+       PUSHJ   P,IILST
+       MOVSI   A,TFORM
+       JRST    MPOPJ
+
+IILST: JUMPE   A,IILST0        ; NIL WHATSIT
+       PUSH    P,A
+       MOVEI   E,0
+IILST1:        POP     TP,D
+       POP     TP,C
+       PUSHJ   P,ICONS         ; CONS 'EM UP
+       MOVEI   E,(B)
+       SOSE    (P)             ; COUNT
+       JRST    IILST1
+
+       SUB     P,C%11  
+       POPJ    P,
+
+IILST0:        MOVEI   B,0
+       POPJ    P,
+
+\f;FUNCTION TO BUILD AN IMPLICIT LIST
+
+MFUNCTION ILIST,SUBR
+       ENTRY
+       PUSH    P,$TLIST
+ILIST2:        JUMPGE  AB,TFA          ;NEED AT LEAST ONE ARG
+       CAMGE   AB,C%M40        ; [-4,,0] ; NO MORE THAN TWO ARGS
+       JRST    TMA
+       PUSHJ   P,GETFIX        ; GET POS FIX #
+       JUMPE   A,LISTN         ;EMPTY LIST ?
+       CAML    AB,C%M20        ; [-2,,0] ;ONLY ONE ARG?
+       JRST    LOSEL           ;YES
+       PUSH    P,A             ;SAVE THE CURRENT VALUE OF LENGTH FOR LOOP ITERATION
+ILIST0:        PUSH    TP,2(AB)
+       PUSH    TP,(AB)3
+       MCALL   1,EVAL
+       PUSH    TP,A
+       PUSH    TP,B
+       SOSLE   (P)
+       JRST    ILIST0
+       POP     P,C
+ILIST1:        MOVE    C,(AB)+1        ;REGOBBLE LENGTH
+       ACALL   C,LIST
+ILIST3:        POP     P,A             ; GET FINAL TYPE
+       JRST    FINIS
+
+
+LOSEL: PUSH    P,A             ; SAVE COUNT
+       MOVEI   E,0
+
+LOSEL1:        SETZB   C,D             ; TLOSE,,0
+       PUSHJ   P,ICONS
+       MOVEI   E,(B)
+       SOSLE   (P)
+       JRST    LOSEL1
+
+       SUB     P,C%11  
+       JRST    ILIST3
+
+; IMPLICIT FORM
+
+MFUNCTION IFORM,SUBR
+
+       ENTRY
+       PUSH    P,$TFORM
+       JRST    ILIST2
+
+\f; IVECTOR AND IUVECTOR--GET VECTOR AND UVECTOR OF COMPUTED VALUES
+
+MFUNCTION VECTOR,SUBR,[IVECTOR]
+
+       MOVEI   C,1
+       JRST    VECTO3
+
+MFUNCTION UVECTOR,SUBR,[IUVECTOR]
+
+       MOVEI   C,0
+VECTO3:        ENTRY
+       JUMPGE  AB,TFA          ; AT LEAST ONE ARG
+       CAMGE   AB,C%M40        ; [-4,,0] ; NOT MORE THAN 2
+       JRST    TMA
+       PUSHJ   P,GETFIX        ; GET A POS FIXED NUMBER
+       LSH     A,(C)           ; A-> NUMBER OF WORDS
+       PUSH    P,C             ; SAVE FOR LATER
+       PUSHJ   P,IBLOCK        ; GET BLOCK (TURN ON BIT APPROPRIATELY)
+       POP     P,C
+       HLRE    A,B             ; START TO
+       SUBM    B,A             ; FIND DOPE WORD
+       MOVSI   D,.VECT.                ; FOR GCHACK
+       IORM    D,(A)
+       JUMPE   C,VECTO4
+       MOVSI   D,400000        ; GET NOT UNIFORM BIT
+       IORM    D,(A)           ; INTO DOPE WORD
+       SKIPA   A,$TVEC         ; GET TYPE
+VECTO4:        MOVSI   A,TUVEC
+       CAML    AB,C%M20        ; [-2,,0] ; SKIP IF ARGS NEED TO BE HACKED
+       JRST    FINIS
+       JUMPGE  B,FINIS         ; DON'T EVAL FOR EMPTY CASE
+
+       PUSH    TP,A            ; SAVE THE VECTOR
+       PUSH    TP,B
+       PUSH    TP,A
+       PUSH    TP,B
+
+       JUMPE   C,UINIT
+       JUMPGE  B,FINIS         ; EMPTY VECTOR, LEAVE
+INLP:  PUSHJ   P,IEVAL         ; EVAL EXPR
+       MOVEM   A,(C)
+       MOVEM   B,1(C)
+       ADD     C,C%22          ; BUMP VECTOR
+       MOVEM   C,(TP)
+       JUMPL   C,INLP          ; IF MORE DO IT
+
+GETVEC:        MOVE    A,-3(TP)
+       MOVE    B,-2(TP)
+       SUB     TP,C%44         ; [4,,4]
+       JRST    FINIS
+
+; HERE TO FILL UP A UVECTOR
+
+UINIT: PUSHJ   P,IEVAL         ; HACK THE 1ST VALUE
+       GETYP   A,A             ; GET TYPE
+       PUSH    P,A             ; SAVE TYPE
+       PUSHJ   P,NWORDT        ; SEE IF IT CAN BE UNIFORMED
+       SOJN    A,CANTUN        ; COMPLAIN
+STJOIN:        MOVE    C,(TP)          ; RESTORE POINTER
+       ADD     C,1(AB)         ; POINT TO DOPE WORD
+       MOVE    A,(P)           ; GET TYPE
+       HRLZM   A,(C)           ; STORE IN D.W.
+       MOVSI   D,.VECT.        ; FOR GCHACK
+       IORM    D,(C)
+       MOVE    C,(TP)          ; GET BACK VECTOR
+       SKIPE   1(AB)
+       JRST    UINLP1          ; START FILLING UV
+       JRST    GETVE1
+
+UINLP: MOVEM   C,(TP)          ; SAVE PNTR
+       PUSHJ   P,IEVAL         ; EVAL THE EXPR
+       GETYP   A,A             ; GET EVALED TYPE
+       CAIE    A,@(P)          ; WINNER?
+       JRST    WRNGSU          ; SERVICE ERROR FOR UVECTOR,STORAGE
+UINLP1:        MOVEM   B,(C)           ; STORE
+       AOBJN   C,UINLP
+GETVE1:        SUB     P,C%11  
+       JRST    GETVEC          ; AND RETURN VECTOR
+
+IEVAL: PUSH    TP,2(AB)
+       PUSH    TP,3(AB)
+       MCALL   1,EVAL
+       MOVE    C,(TP)
+       POPJ    P,
+
+; ISTORAGE -- GET STORAGE OF COMPUTED VALUES
+
+MFUNCTION ISTORAGE,SUBR
+       ENTRY
+       JUMPGE  AB,TFA
+       CAMGE   AB,C%M40        ; [-4,,0] ; AT LEAST ONE ARG
+       JRST    TMA
+       PUSHJ   P,GETFIX        ; POSITIVE COUNT FIRST ARG
+       PUSHJ   P,CAFRE         ; GET CORE
+       MOVN    B,1(AB)         ; -COUNT
+       HRL     A,B             ; PUT IN LHW (A)
+       MOVM    B,B             ; +COUNT
+       HRLI    B,2(B)          ; LENGTH + 2
+       ADDI    B,(A)           ; MAKE POINTER TO DOPE WORDS
+       HLLZM   B,1(B)          ; PUT TOTAL LENGTH IN 2ND DOPE
+       HRRM    A,1(B)          ; PUT ADDRESS IN RHW (STORE DOES THIS TOO).
+       MOVE    B,A
+       MOVSI   A,TSTORAGE
+       CAML    AB,C%M20        ; [-2,,0] ; SECOND ARG TO EVAL?
+       JRST     FINIS          ; IF NOT, RETURN EMPTY
+       PUSH    TP,A
+       PUSH    TP,B
+       PUSH    TP,A
+       PUSH    TP,B
+       PUSHJ   P,IEVAL         ; EVALUATE FOR FIRST VALUE
+       GETYP   A,A
+       PUSH    P,A             ; FOR COMPARISON LATER
+       PUSHJ   P,SAT
+       CAIN    A,S1WORD
+       JRST    STJOIN          ;TREAT LIKE A UVECTOR
+; IF NOT 1-WORD TYPES, CANNOT STORE, SO COMPLAIN
+       PUSHJ   P,FREESV        ; FREE STORAGE VECTOR
+       ERRUUO  EQUOTE DATA-CANT-GO-IN-STORAGE
+
+; FOR STORAGE, MUST FREE THE CORE ELSE IT IS LOST (NO GC)
+FREESV:        MOVE    A,1(AB)         ; GET COUNT
+       ADDI    A,2             ; FOR DOPE
+       HRRZ    B,(TP)          ; GET ADDRESS
+       PUSHJ   P,CAFRET        ; FREE THE CORE
+       POPJ    P,
+
+\f
+; INTERNAL VECTOR ALLOCATOR.  A/SIZE OF VECTOR (NOT INCLUDING DOPE WORDS)
+
+IBLOK1:        ASH     A,1             ; TIMES 2
+GIBLOK:        TLOA    A,400000        ; FUNNY BIT
+IBLOCK:        TLZ     A,400000        ; NO BIT ON
+       TLO     A,.VECT.        ; TURN ON BIT FOR GCHACK
+       ADDI    A,2             ; COMPENSATE FOR DOPE WORDS
+IBLOK2:        SKIPE   B,RCLV          ; ANY TO RECYCLE?
+       JRST    RCLVEC
+NORCL: MOVE    B,GCSTOP        ; POINT TO BOTTOM OF SPACE
+       PUSH    P,B             ; SAVE TO BUILD PTR
+       ADDI    B,(A)           ; ADD NEEDED AMOUNT
+       CAML    B,FRETOP        ; SKIP IF NO GC NEEDED
+       JRST    IVECT1
+       MOVEM   B,GCSTOP        ; WIN, GET POINTER TO BLOCK AND UPDATE VECBOT
+       ADDM    A,USEFRE
+       HRRZS   USEFRE
+       HRLZM   A,-1(B)         ; STORE LENGTH IN DOPE WORD
+       HLLZM   A,-2(B)         ; AND BIT
+       HRRM    B,-1(B)         ; SMASH IN RELOCATION
+       SOS     -1(B)
+       POP     P,B             ; RESTORE PTR TO BOTTOM OF VECTOR
+       HRROS   B               ; POINT TO START OF VECTOR
+       TLC     B,-3(A)         ; SETUP COUNT
+       HRRI    A,TVEC
+       SKIPL   A
+       HRRI    A,TUVEC
+       MOVSI   A,(A)
+       POPJ    P,
+
+; HERE TO DO A GC ON A VECTOR ALLOCATION
+
+IVECT1:        PUSH    P,0
+       PUSH    P,A             ; SAVE DESIRED LENGTH
+       HRRZ    0,A
+       ADDM    0,GETNUM        ; AND STORE AS DESIRED AMOUNT
+       MOVE    C,[4,,1]        ; GET INDICATOR FOR AGC
+       PUSHJ   P,INQAGC
+       POP     P,A
+       POP     P,0
+       POP     P,B
+       JRST    IBLOK2
+
+
+; INTERNAL EVECTOR (CALLED FROM READ) A/ #OF THINGS
+; ITEMS ON TOP OF STACK
+
+IEVECT:        ASH     A,1             ; TO NUMBER OF WORDS
+       PUSH    P,A
+       PUSHJ   P,IBLOCK        ; GET VECTOR
+       HLRE    D,B             ; FIND DW
+       SUBM    B,D             ; A POINTS TO DW
+       MOVSI   0,400000+.VECT.
+       MOVEM   0,(D)           ; CLOBBER NON UNIF BIT
+       POP     P,A             ; RESTORE COUNT
+       JUMPE   A,IVEC1         ; 0 LNTH, DONE
+       MOVEI   C,(TP)          ; BUILD BLT
+       SUBI    C,(A)-1         ; C POINTS TO 1ST ITEM ON STACK
+       MOVSI   C,(C)
+       HRRI    C,(B)           ; B/ SOURCE,,DEST
+       BLT     C,-1(D)         ; XFER THE DATA
+       HRLI    A,(A)
+       SUB     TP,A            ; FLUSH STACKAGE
+IVEC1: MOVSI   A,TVEC
+       POPJ    P,
+       
+
+; COMPILERS CALL
+
+CIVEC: SUBM    M,(P)
+       PUSHJ   P,IEVECT
+       JRST    MPOPJ
+
+
+\f; INTERNAL CALL TO EUVECTOR
+
+IEUVEC:        PUSH    P,A             ; SAVE LENGTH
+       PUSHJ   P,IBLOCK
+       MOVE    A,(P)
+       JUMPE   A,IEUVE1        ; EMPTY, LEAVE
+       ASH     A,1             ; NOW FIND STACK POSITION
+       MOVEI   C,(TP)          ; POINT TO TOP
+       MOVE    D,B             ; COPY VEC POINTER
+       SUBI    C,-1(A)         ; POINT TO 1ST DATUM
+       GETYP   A,(C)           ; CHECK IT
+       PUSHJ   P,NWORDT
+       SOJN    A,CANTUN        ; WONT FIT
+       GETYP   E,(C)
+
+IEUVE2:        GETYP   0,(C)           ; TYPE OF EL
+       CAIE    0,(E)           ; MATCH?
+       JRST    WRNGUT
+       MOVE    0,1(C)
+       MOVEM   0,(D)           ; CLOBBER
+       ADDI    C,2
+       AOBJN   D,IEUVE2        ; LOOP
+       TRO     E,.VECT.
+       HRLZM   E,(D)           ; STORE UTYPE
+IEUVE1:        POP     P,A             ; GET COUNY
+       ASH     A,1             ; MUST FLUSH 2 TIMES # OF ELEMENTS
+       HRLI    A,(A)
+       SUB     TP,A            ; CLEAN UP STACK
+       MOVSI   A,TUVEC
+       POPJ    P,
+
+; COMPILER'S CALL
+
+CIUVEC:        SUBM    M,(P)
+       PUSHJ   P,IEUVEC
+       JRST    MPOPJ
+
+IMFUNCTION EVECTOR,SUBR,[VECTOR]
+       ENTRY
+       HLRE    A,AB
+       MOVNS   A
+       PUSH    P,A             ;SAVE NUMBER OF WORDS
+       PUSHJ   P,IBLOCK        ; GET WORDS
+       MOVEI   D,-1(B)         ; SETUP FOR BLT AND DOPE CLOBBER
+       JUMPGE  B,FINISV                ;DONT COPY A ZERO LENGTH VECTOR
+
+       HRLI    C,(AB)          ;START BUILDING BLT POINTER
+       HRRI    C,(B)           ;TO ADDRESS
+       ADDI    D,@(P)          ;SET D TO FINAL ADDRESS
+       BLT     C,(D)
+FINISV:        MOVSI   0,400000+.VECT.
+       MOVEM   0,1(D)          ; MARK AS GENERAL
+       SUB     P,C%11  
+       MOVSI   A,TVEC
+       JRST    FINIS
+
+
+
+\f;EXPLICIT VECTORS FOR THE UNIFORM CSE
+
+IMFUNCTION EUVECTOR,SUBR,[UVECTOR]
+
+       ENTRY
+       HLRE    A,AB            ;-NUM OF ARGS
+       MOVNS   A
+       ASH     A,-1            ;NEED HALF AS MANY WORDS
+       PUSH    P,A
+       JUMPGE  AB,EUV1         ; DONT CHECK FOR EMPTY
+       GETYP   A,(AB)          ;GET FIRST ARG
+       PUSHJ   P,NWORDT                ;SEE IF NEEDS EXTRA WORDS
+       SOJN    A,CANTUN
+EUV1:  POP     P,A
+       PUSHJ   P,IBLOCK        ; GET VECT
+       JUMPGE  B,FINISU
+
+       GETYP   C,(AB)          ;GET THE FIRST TYPE
+       MOVE    D,AB            ;COPY THE ARG POINTER
+       MOVE    E,B             ;COPY OF RESULT
+
+EUVLP: GETYP   0,(D)           ;GET A TYPE
+       CAIE    0,(C)           ;SAME?
+       JRST    WRNGUT          ;NO , LOSE
+       MOVE    0,1(D)          ;GET GOODIE
+       MOVEM   0,(E)           ;CLOBBER
+       ADD     D,C%22          ;BUMP ARGS POINTER
+       AOBJN   E,EUVLP
+
+       TRO     C,.VECT.
+       HRLM    C,(E)           ;CLOBBER UNIFORM TYPE IN
+FINISU:        MOVSI   A,TUVEC
+       JRST    FINIS
+
+WRNGSU:        GETYP   A,-1(TP)
+       CAIE    A,TSTORAGE
+       JRST    WRNGUT          ;IF UVECTOR
+       PUSHJ   P,FREESV        ;FREE STORAGE VECTOR
+       ERRUUO  EQUOTE TYPES-DIFFER-IN-STORAGE-OBJECT
+       
+WRNGUT:        ERRUUO  EQUOTE TYPES-DIFFER-IN-UNIFORM-VECTOR
+
+CANTUN:        ERRUUO  EQUOTE DATA-CANT-GO-IN-UNIFORM-VECTOR
+
+BADNUM:        ERRUUO  EQUOTE NEGATIVE-ARGUMENT
+\f; FUNCTION TO GROW A VECTOR
+REPEAT 0,[
+MFUNCTION GROW,SUBR
+
+       ENTRY   3
+
+       MOVEI   D,0             ;STACK HACKING FLAG
+       GETYP   A,(AB)          ;FIRST TYPE
+       PUSHJ   P,SAT           ;GET STORAGE TYPE
+       GETYP   B,2(AB)         ;2ND ARG
+       CAIE    A,STPSTK        ;IS IT ASTACK
+       CAIN    A,SPSTK
+       AOJA    D,GRSTCK        ;YES, WIN
+       CAIE    A,SNWORD        ;UNIFORM VECTOR
+       CAIN    A,S2NWORD       ;OR GENERAL
+GRSTCK:        CAIE    B,TFIX          ;IS 2ND FIXED
+       JRST    WTYP2           ;COMPLAIN
+       GETYP   B,4(AB)
+       CAIE    B,TFIX          ;3RD ARG
+       JRST    WTYP3           ;LOSE
+
+       MOVEI   E,1             ;UNIFORM/GENERAL FLAG
+       CAIE    A,SNWORD        ;SKIP IF UNIFORM
+       CAIN    A,SPSTK         ;DONT SKIP IF UNIFORM PDL
+       MOVEI   E,0
+
+       HRRZ    B,1(AB)         ;POINT TO START
+       HLRE    A,1(AB)         ;GET -LENGTH
+       SUB     B,A             ;POINT TO DOPE WORD
+       SKIPE   D               ;SKIP IF NOT STACK
+       ADDI    B,PDLBUF        ;FUDGE FOR PDL
+       HLLZS   (B)             ;ZERO OUT GROWTH SPECS
+       SKIPN   A,3(AB)         ;ANY TOP GROWTH?
+       JRST    GROW1           ;NO, LOOK FOR BOTTOM GROWTH
+       ASH     A,(E)           ;MULT BY 2 IF GENERAL
+       ADDI    A,77            ;ROUND TO NEAREST BLOCK
+       ANDCMI  A,77            ;CLEAR LOW ORDER BITS
+       ASH     A,9-6           ;DIVIDE BY 100 AND SHIFT TO POSTION
+       TRZE    A,400000        ;CONVERT TO SIGN MAGNITUDE
+       MOVNS   A
+       TLNE    A,-1            ;SKIP IF NOT TOO BIG
+       JRST    GTOBIG          ;ERROR
+GROW1: SKIPN   C,5(AB)         ;CHECK LOW GROWTH
+       JRST    GROW4           ;NONE, SKIP
+       ASH     C,(E)           ;GENRAL FUDGE
+       ADDI    C,77            ;ROUND
+       ANDCMI  C,77            ;FUDGE FOR VALUE RETURN
+       PUSH    P,C             ;AND SAVE
+       ASH     C,-6            ;DIVIDE BY 100
+       TRZE    C,400           ;CONVERT TO SIGN MAGNITUDE
+       MOVNS   C
+       TDNE    C,[-1,,777000]  ;CHECK FOR OVERFLOW
+       JRST    GTOBIG
+GROW2: HLRZ    E,1(B)          ;GET TOTAL LENGTH OF VECTOR
+       MOVNI   E,-1(E)
+       HRLI    E,(E)           ;TO BOTH HALVES
+       ADDI    E,1(B)          ;POINTS TO TOP
+       SKIPE   D               ;STACK?
+       ADD     E,[PDLBUF,,0]   ;YES, FUDGE LENGTH
+       SKIPL   D,(P)           ;SHRINKAGE?
+       JRST    GROW3           ;NO, CONTINUE
+       MOVNS   D               ;PLUSIFY
+       HRLI    D,(D)           ;TO BOTH HALVES
+       ADD     E,D             ;POINT TO NEW LOW ADDR
+GROW3: IORI    A,(C)           ;OR TOGETHER
+       HRRM    A,(B)           ;DEPOSIT INTO DOPEWORD
+       PUSH    TP,(AB)         ;PUSH TYPE
+       PUSH    TP,E            ;AND VALUE
+       SKIPE   A               ;DON'T GC FOR NOTHING
+       MOVE    C,[2,,0]        ; GET INDICATOR FOR AGC
+       PUSHJ   P,AGC
+       JUMPL   A,GROFUL
+       POP     P,C             ;RESTORE GROWTH
+       HRLI    C,(C)
+       POP     TP,B            ;GET VECTOR POINTER
+       SUB     B,C             ;POINT TO NEW TOP
+       POP     TP,A
+       JRST    FINIS
+
+GROFUL:        SUB     P,C%11          ; CLEAN UP STACK
+       SUB     TP,C%22
+       PUSHJ   P,FULLOS
+       JRST    GROW
+
+GTOBIG:        ERRUUO  EQUOTE ATTEMPT-TO-GROW-VECTOR-TOO-MUCH
+GROW4: PUSH    P,[0]           ;0 BOTTOM GROWTH
+       JRST    GROW2
+]
+FULLOS:        ERRUUO  EQUOTE NO-STORAGE
+
+
+\f; SUBROUTINE TO BUILD CHARACTER STRING GOODIES
+
+MFUNCTION BYTES,SUBR
+
+       ENTRY
+       MOVEI   D,1
+       JUMPGE  AB,TFA
+       GETYP   0,(AB)
+       CAIE    0,TFIX
+       JRST    WTYP1
+       MOVE    E,1(AB)
+       ADD     AB,C%22
+       JRST    STRNG1
+
+IMFUNCTION STRING,SUBR
+
+       ENTRY
+
+       MOVEI   D,0
+       MOVEI   E,7
+STRNG1:        MOVE    B,AB            ;COPY ARG POINTER
+       MOVEI   C,0             ;INITIALIZE COUNTER
+       PUSH    TP,$TAB         ;SAVE A COPY
+       PUSH    TP,B
+       HLRE    A,B             ; GET # OF ARGS
+       MOVNS   A
+       ASH     A,-1            ; 1/2 FOR # OF ARGS
+       PUSHJ   P,IISTRN
+       JRST    FINIS
+
+IISTRN:        PUSH    P,E
+       JUMPL   E,OUTRNG
+       CAILE   E,36.
+       JRST    OUTRNG
+       SKIPN   E,A             ; SKIP IF ARGS EXIST
+       JRST    MAKSTR          ; ALL DONE
+
+STRIN2:        GETYP   0,(B)           ;GET TYPE CODE
+       CAMN    0,SING(D)       ; SINGLE CHARACTER OR FIX?
+       AOJA    C,STRIN1
+       CAME    0,MULTI(D)      ; OR STRING OR BYTE-STRING
+       JRST    WRONGT          ;NEITHER
+       HRRZ    0,(B)           ; GET CHAR COUNT
+       ADD     C,0             ; AND BUMP
+
+STRIN1:        ADD     B,C%22
+       SOJG    A,STRIN2
+
+; NOW GET THE NECESSARY VECTOR
+
+MAKSTR:        HRL     C,MULTI(D)              ; FINAL TYPE,, CHAR COUNT
+       PUSH    P,C             ; SAVE CHAR COUNT
+       PUSH    P,E             ; SAVE ARG COUNT
+       MOVEI   D,36.
+       IDIV    D,-2(P)         ; A==> BYTES PER WORD
+       MOVEI   A,(C)           ; LNTH+4 TO A
+       ADDI    A,-1(D)
+       IDIVI   A,(D)
+       LSH     E,12.
+       MOVE    D,-2(P)
+       DPB     D,[060600,,E]
+       HRLM    E,-2(P)         ; SAVE REMAINDER
+       PUSHJ   P,IBLOCK
+
+       POP     P,A
+       JUMPGE  B,DONEC         ; 0 LENGTH, NO STRING
+       HRLI    B,440000        ;CONVERT B TO A BYTE POINTER
+       HRRZ    0,-1(P)         ; BYTE SIZE
+       DPB     0,[300600,,B]
+       MOVE    C,(TP)          ; POINT TO ARGS AGAIN
+
+NXTRG1:        GETYP   D,(C)           ;GET AN ARG
+       CAIN    D,TFIX
+        JRST   .+3
+       CAIE    D,TCHRS
+        JRST   TRYSTR
+       MOVE    D,1(C)                  ; GET IT
+       IDPB    D,B             ;AND DEPOSIT IT
+       JRST    NXTARG
+
+TRYSTR:        MOVE    E,1(C)          ;GET BYTER
+       HRRZ    0,(C)           ;AND COUNT
+NXTCHR:        SOJL    0,NXTARG        ; IF RUNOUT, GET NEXT ARG
+       ILDB    D,E             ;AND GET NEXT
+       IDPB    D,B             ; AND DEPOSIT SAME
+       JRST    NXTCHR
+
+NXTARG:        ADD     C,C%22          ;BUMP ARG POINTER
+       SOJG    A,NXTRG1
+       ADDI    B,1
+
+DONEC: MOVSI   C,TCHRS+.VECT.
+       TLO     B,400000
+       HLLM    C,(B)           ;AND CLOBBER AWAY
+       HLRZ    C,1(B)          ;GET LENGTH BACK
+       POP     P,A
+       SUBI    B,-1(C)
+       HLL     B,(P)           ;MAKE A BYTE POINTER
+       SUB     P,C%11  
+       POPJ    P,
+
+SING:  TCHRS
+       TFIX
+
+MULTI: TCHSTR
+       TBYTE
+
+
+; COMPILER'S CALL TO MAKE A STRING
+
+CISTNG:        TDZA    D,D
+
+; COMPILERS CALL TO MAKE A BYTE STRING
+
+CBYTES:        MOVEI   D,1
+       SUBM    M,(P)
+       MOVEI   C,0             ; INIT CHAR COUNTER
+       MOVEI   B,(A)           ; SET UP STACK POINTER
+       ASH     B,1             ; * 2 FOR NO. OF SLOTS
+       HRLI    B,(B)
+       SUBM    TP,B            ; B POINTS TO ARGS
+       PUSH    P,D
+       MOVEI   E,7
+       JUMPE   D,CBYST
+       GETYP   0,1(B)          ; CHECK BYTE SIZE
+       CAIE    0,TFIX
+       JRST    WRONGT
+       MOVE    E,2(B)
+       ADD     B,C%22  
+       SUBI    A,1
+CBYST: ADD     B,C%11  
+       PUSH    TP,$TTP
+       PUSH    TP,B
+       PUSHJ   P,IISTRN        ; MAKE IT HAPPEN
+       MOVE    TP,(TP)         ; FLUSH ARGS
+       SUB     TP,C%11 
+       POP     P,D
+       JUMPE   D,MPOPJ
+       SUB     TP,C%22
+       JRST    MPOPJ
+
+\f;BUILD IMPLICT STRING
+
+MFUNCTION IBYTES,SUBR
+
+       ENTRY
+
+       CAML    AB,C%M20                ; [-3,,] ; AT LEAST 2
+        JRST   TFA
+       CAMGE   AB,C%M60                ; [-7,,] ; NO MORE THAN 3
+        JRST   TMA
+       PUSHJ   P,GETFIX        ; GET BYTE SIZE
+       JUMPL   A,OUTRNG
+       CAILE   A,36.
+        JRST   OUTRNG
+       PUSH    P,[TFIX]
+       PUSH    P,A
+       PUSH    P,$TBYTE
+       ADD     AB,C%22
+       MOVEM   AB,ABSAV(TB)
+       JRST    ISTR1
+
+MFUNCTION ISTRING,SUBR
+
+       ENTRY
+       JUMPGE  AB,TFA          ; TOO FEW ARGS
+       CAMGE   AB,C%M40        ; [-4,,0] ; VERIFY NOT TOO MANY ARGS
+        JRST   TMA
+       PUSH    P,[TCHRS]
+       PUSH    P,[7]
+       PUSH    P,$TCHSTR
+ISTR1: PUSHJ   P,GETFIX
+       MOVEI   C,36.
+       IDIV    C,-1(P)
+       ADDI    A,-1(C)
+       IDIVI   A,(C)           ; # OF WORDS NEEDED TO A
+       ASH     D,12.
+       MOVE    C,-1(P)         ; GET BYTE SIZE
+       DPB     C,[060600,,D]
+       PUSH    P,D
+       PUSHJ   P,IBLOCK
+       HLRE    C,B             ; -LENGTH TO C
+       SUBM    B,C             ; LOCN OF DOPE WORD TO C
+       HRLI    D,TCHRS+.VECT.  ; CLOBBER ITS TYPE
+       HLLM    D,(C)
+       MOVE    A,-1(P)
+       HRR     A,1(AB)         ; SETUP TYPE'S RH
+       SUBI    B,1
+       HRL     B,(P)           ; AND BYTE POINTER
+       SUB     P,C%33
+       SKIPE   (AB)+1          ; SKIP IF NO CHARACTERS TO DEPOSIT
+       CAML    AB,C%M20        ; [-2,,0] ; SKIP IF 2 ARGS GIVEN
+        JRST   FINIS
+       PUSH    TP,A            ;SAVE OUR STRING
+       PUSH    TP,B
+       PUSH    TP,A            ;SAVE A TEMPORARY CLOBBER POINTER
+       PUSH    TP,B
+       PUSH    P,(AB)1         ;SAVE COUNT
+       PUSH    TP,(AB)+2
+       PUSH    TP,(AB)+3
+CLOBST:        PUSH    TP,-1(TP)
+       PUSH    TP,-1(TP)
+       MCALL   1,EVAL
+       GETYP   C,A             ; CHECK IT
+       CAME    C,-1(P)         ; MUST BE A CHARACTER
+        JRST   WTYP2
+       IDPB    B,-2(TP)        ;CLOBBER
+       SOSLE   (P)             ;FINISHED?
+        JRST   CLOBST          ;NO
+       SUB     P,C%22
+       SUB     TP,C%66
+       MOVE    A,(TP)+1
+       MOVE    B,(TP)+2
+       JRST    FINIS
+
+\f
+; HERE TO CHECK TO SEE WHETHER PURE RSUBR'S ARE MAPPED BELOW FRETOP AND
+;      PUNT SOME IF THERE ARE.
+
+INQAGC:        PUSH    P,C
+       PUSH    P,B
+       PUSH    P,A
+       PUSH    P,E
+       PUSHJ   P,SQKIL
+       JSP     E,CKPUR         ; CHECK FOR PURE RSUBR
+       POP     P,E
+       MOVE    A,PURTOP
+       SUB     A,CURPLN
+       MOVE    B,RFRETP        ; GET REAL FRETOP
+       CAIL    B,(A)
+       MOVE    B,A             ; TOP OF WORLD
+       MOVE    A,GCSTOP
+       ADD     A,GETNUM
+       ADDI    A,1777          ; PAGE BOUNDARY
+       ANDCMI  A,1777
+       CAIL    A,(B)           ; SEE WHETHER THERE IS ROOM
+       JRST    GOTOGC
+       PUSHJ   P,CLEANT
+       POP     P,A
+       POP     P,B
+       POP     P,C
+       POPJ    P,
+GOTOGC:        POP     P,A
+       POP     P,B
+       POP     P,C             ; RESTORE CAUSE INDICATOR
+       MOVE    A,P.TOP
+       PUSHJ   P,CLEANT        ; CLEAN UP
+       SKIPL   PLODR           ; IF IN PLOAD DON'T INTERRUPT
+        JRST   INTAGC          ; GO CAUSE GARBAGE COLLECT
+       JRST    SAGC
+
+CLEANT:        PUSH    P,C
+       PUSH    P,A
+       SUB     A,P.TOP
+       ASH     A,-PGSZ
+       JUMPE   A,CLNT1
+       PUSHJ   P,GETPAG                ; GET THOSE PAGES
+       FATAL CAN'T GET PAGES NEEDED
+       MOVE    A,(P)
+       ASH     A,-10.                  ; TO PAGES
+       PUSHJ   P,P.CORE
+       PUSHJ   P,SLEEPR
+CLNT1: PUSHJ   P,RBLDM
+       POP     P,A
+       POP     P,C
+       POPJ    P,
+
+\f; RCLVEC DISTASTEFUL VECTOR RECYCLER
+
+; Arrive here with B pointing to first recycler, A desired length
+
+RCLVEC:        PUSH    P,D             ; Save registers
+       PUSH    P,C
+       PUSH    P,E
+       MOVEI   D,RCLV          ; Point to previous recycle for splice
+RCLV1: HLRZ    C,(B)           ; Get size of this block
+       CAIL    C,(A)           ; Skip if too small
+       JRST    FOUND1
+
+RCLV2: MOVEI   D,(B)           ; Save previous pointer
+       HRRZ    B,(B)           ; Point to next block
+       JUMPN   B,RCLV1         ; Jump if more blocks
+
+       POP     P,E
+       POP     P,C
+       POP     P,D
+       JRST    NORCL           ; Go to normal allocator
+
+
+FOUND1:        CAIN    C,1(A)          ; Exactly 1 greater?
+       JRST    RCLV2           ; Cant use this guy
+
+       HRLM    A,(B)           ; Smash in new count
+       TLO     A,.VECT.        ; make vector bit be on
+       HLLM    A,-1(B)
+       CAIE    C,(A)           ; Exactly right length?
+       JRST    FOUND2          ; No, do hair
+
+       HRRZ    C,(B)           ; Point to next block
+       HRRM    C,(D)           ; Smash previous pointer
+       HRRM    B,(B)
+       SUBI    B,-1(A)         ; Point to top of block
+       JRST    FOUND3
+
+FOUND2:        SUBI    C,(A)           ; Amount of left over to C
+       HRRZ    E,(B)           ; Point to next block
+       HRRM    B,(B)
+       SUBI    B,(A)           ; Point to dope words of guy to put back
+       MOVSM   C,(B)           ; Smash in count
+       MOVSI   C,.VECT.        ; Get vector bit
+       MOVEM   C,-1(B)         ; Make sure it is a vector
+       HRRM    B,(D)           ; Splice him in
+       HRRM    E,(B)           ; And the next guy also
+       ADDI    B,1             ; Point to start of vector
+
+FOUND3:        HRROI   B,(B)           ; Make an AOBJN pointer
+       TLC     B,-3(A)
+       HRRI    A,TVEC
+       SKIPGE  A
+       HRRI    A,TUVEC
+       MOVSI   A,(A)
+       POP     P,E
+       POP     P,C
+       POP     P,D
+       POPJ    P,
+
+END
+\f
\ No newline at end of file