Twenex Muddle.
[pdp10-muddle.git] / <mdl.int> / primit.mid.315
diff --git a/<mdl.int>/primit.mid.315 b/<mdl.int>/primit.mid.315
new file mode 100644 (file)
index 0000000..5e79bde
--- /dev/null
@@ -0,0 +1,2822 @@
+TITLE PRIMITIVE FUNCTIONS FOR THE MUDDLE SYSTEM
+
+RELOCATABLE
+
+.INSRT MUDDLE >
+
+.GLOBAL TMA,TFA,CELL,IBLOCK,IBLOK1,ICELL2,VECTOP,LSTUF,PVSTOR,SPSTOR
+.GLOBAL NWORDT,CHARGS,CHFRM,CHLOCI,IFALSE,IPUTP,IGETP,BYTDOP
+.GLOBAL OUTRNG,IGETLO,CHFRAM,ISTRUC,TYPVEC,SAT,CHKAB,VAL,CELL2,MONCH,MONCH0
+.GLOBAL RMONCH,RMONC0,LOCQ,LOCQQ,SMON,PURERR,APLQ,NAPT,TYPSEG,NXTLM
+.GLOBAL MAKACT,ILLCHO,COMPER,CEMPTY,CIAT,CIEQUA,CILEGQ,CILNQ,CILNT,CIN,CINTH,CIREST
+.GLOBAL CISTRU,CSETLO,CIPUT,CIGET,CIGETL,CIMEMQ,CIMEMB,CIMON,CITOP,CIBACK
+.GLOBAL IGET,IGETL,IPUT,CIGETP,CIGTPR,CINEQU,IEQUAL,TD.LNT,TD.GET,TD.PUT,TD.PTY
+.GLOBAL TMPLNT,BADTPL,ISTRCM,PTYPE,CIGVAL,MAKTUP,CSBSTR,TMATCH
+
+; BUILD DISPATCH TABLE FOR PRIMITIVE FUNCTIONS USAGE
+F==PVP
+
+PRMTYP:
+
+REPEAT NUMSAT+1,[0]                    ;INITIALIZE TABLE TO ZEROES
+
+IRP A,,[2WORD,2NWORD,NWORD,ARGS,CHSTR,BYTE]
+
+LOC PRMTYP+S!A
+P!A==.IRPCN+1
+P!A
+
+TERMIN
+
+PTMPLT==PBYTE+1
+
+; FUDGE FOR STRUCTURE LOCATIVES
+
+IRP A,,[[LOCL,2WORD],[LOCV,2NWORD],[LOCU,NWORD],[LOCS,CHSTR],[LOCA,ARGS]
+[LOCT,TMPLT],[LOCB,BYTE]]
+       IRP B,C,[A]
+       LOC PRMTYP+S!B
+       P!B==P!C,,0
+       P!B
+       .ISTOP
+       TERMIN
+TERMIN
+
+LOC PRMTYP+SSTORE      ;SPECIAL HACK FOR AFREE STORAGE
+PNWORD
+
+LOC PRMTYP+NUMSAT+1
+
+PNUM==PTMPLT+1
+
+; MACRO TO BUILD PRIMITIVE DISPATCH TABLES
+
+DEFINE PRDISP NAME,DEFAULT,LIST
+       TBLDIS NAME,DEFAULT,[LIST]PNUM,400000
+       TERMIN
+
+
+; SUBROUTINE TO RETURN PRIMITIVE TYPE AND PRINT ERROR IF ILLEGAL
+
+PTYPE: GETYP   A,(B)   ;CALLE D WITH B POINTING TO PAIR
+       CAIN    A,TILLEG        ;LOSE IF ILLEGAL
+       JRST    ILLCHOS
+
+       PUSHJ   P,SAT           ;GET STORAGE ALLOC TYPE
+       CAIE    A,SLOCA
+       CAIN    A,SARGS         ;SPECIAL HAIR FOR ARGS
+       PUSHJ   P,CHARGS
+       CAIN    A,SFRAME
+       PUSHJ   P,CHFRM
+       CAIN    A,SLOCID
+       PUSHJ   P,CHLOCI
+PTYP1: MOVEI   0,(A)           ; ALSO RETURN PRIMTYPE
+       CAILE   A,NUMSAT        ; SKIP IF NOT TEMPLATE
+       SKIPA   A,[PTMPLT]
+       MOVE    A,PRMTYP(A)     ;GET PRIM TYPE,
+       POPJ    P,
+
+; COMPILERS CALL TO ABOVE (LESS CHECKING)
+
+CPTYPE:        PUSHJ   P,SAT
+       MOVEI   0,(A)
+       CAILE   A,NUMSAT
+       SKIPA   A,[PTMPLT]
+       MOVE    A,PRMTYP(A)
+       POPJ    P,
+
+
+MFUNCTION SORT,SUBR
+
+       ENTRY
+
+; HACK TO DYNAMICALLY LOAD SORT
+       MOVE    B,MQUOTE SORTX
+       PUSHJ   P,CIGVAL
+       PUSH    TP,A
+       PUSH    TP,B            ; PUSH ON FUNCTION FOR APPLY
+       MOVE    A,AB            ; PUSH ARGS TO SORT ONTO STACK
+       JUMPE   A,DONPSH
+       PUSH    TP,(A)
+       AOBJN   A,.-1
+DONPSH:        HLRE    A,AB            ; GET COUNT
+       MOVNS   A
+       ADDI    A,2
+       ASH     A,-1            ; # OF ARGS
+       ACALL   A,APPLY
+       JRST    FINIS
+
+\f
+MFUNCTION SUBSTRUC,SUBR
+
+       ENTRY
+       JUMPGE  AB,TFA  ;need at least one arg
+       CAMGE   AB,[-10,,0]     ;NO MORE THEN 4
+       JRST    TMA
+       HLRE    A,AB            ; GET NEGATIVE LENGTH IN A
+       MOVNS   A               ; SET UP LENGTH ARG TO SUBSTRUC
+       ASH     A,-1
+       MOVE    B,AB            ; AOBJN POINTER FOR LOOP
+       PUSH    TP,(B)          ; PUSH ON ARGS
+       AOBJN   B,.-1
+       PUSHJ   P,CSBSTR        ; GO TO INTERNAL ROUTINE
+       JRST    FINIS
+
+; VARIOUS OFFSETS INTO PSTACK
+
+PRTYP==0
+LNT==0
+NOARGS==-1
+
+; VARIOUS OFFSETS INTO TP STACK
+
+OBJ==-7
+RSTR==-5
+LNT==-3
+NOBJ==-1
+
+; THIS STARTS THE MAIN ROUTINE
+
+CSBSTR:        SUBM    M,(P)           ; FOR RSUBRS
+       JSP     E,@PTBL(A)
+       MOVEI   B,OBJ(TP)
+       PUSH    P,A
+       PUSHJ   P,PTYPE         ; get primtype in A
+       PUSH    P,A
+       JRST    @TYTBL(A)
+
+PTBL:  SETZ    WNA
+       SETZ    PUSH6
+       SETZ    PUSH4
+       SETZ    PUSH2
+       SETZ    PUSH0
+
+PUSH6: PUSH    TP,[0]
+       PUSH    TP,[0]
+PUSH4: PUSH    TP,[0]
+       PUSH    TP,[0]
+PUSH2: PUSH    TP,[0]
+       PUSH    TP,[0]
+PUSH0: JRST    (E)
+
+
+RESSUB:        MOVE    D,NOARGS(P)             ; GET NUMBER OF ARGS
+       CAIN    D,1                     ; IF 1 THEN JUST COPY
+       JRST    @COPYTB(A)
+       GETYP   B,RSTR(TP)              ; GET TYPE OF REST ARGUMENT
+       CAIE    B,TFIX                  ;IF FIX OK
+       JRST    WRONGT
+       MOVEI   E,(A)
+       MOVE    A,OBJ(TP)
+       MOVE    B,OBJ+1(TP)             ; GET OBJECT
+       SKIPGE  C,RSTR+1(TP)            ; GET REST ARGUMENT
+       JRST    OUTRNG
+       PUSHJ   P,@MRSTBL(E)
+       PUSH    TP,A                    ; type
+       PUSH    TP,B                    ; put rested sturc on stack
+       JRST    ALOCOK
+
+PRDISP TYTBL,IWTYP1,[[PARGS,RESSUB],[P2WORD,RESSUB],[P2NWORD,RESSUB]
+[PNWORD,RESSUB],[PCHSTR,RESSUB],[PBYTE,RESSUB]]
+
+PRDISP MRSTBL,IWTYP1,[[PARGS,AREST],[P2WORD,LREST],[P2NWORD,VREST]
+[PNWORD,UREST],[PCHSTR,SREST],[PBYTE,BREST]]
+
+PRDISP COPYTB,IWTYP1,[[PARGS,CPYVEC],[P2WORD,CPYLST],[P2NWORD,CPYVEC]
+[PNWORD,CPYUVC],[PCHSTR,CPYSTR],[PBYTE,CPYBYT]]
+
+PRDISP ALOCTB,IWTYP1,[[PARGS,ALVEC],[P2WORD,ALLIST],[P2NWORD,ALVEC]
+[PNWORD,ALUVEC],[PCHSTR,ALSTR],[PBYTE,ALBYT]]
+
+; HERE WE HAVE RESTED STRUCTURE ON TOP OF STACK
+
+ALOCFX:        MOVE    B,(TP)          ; missing 3rd arg aloc for "rest" of struc
+       MOVE    C,-1(TP)
+       MOVE    A,(P)
+       PUSH    P,[377777,,-1]
+       PUSHJ   P,@LENTBL(A)    ; get length of rested struc
+       SUB     P,[1,,1]
+       POP     P,C
+       MOVE    A,B             ; # of elements needed
+       JRST    @ALOCTB(C)
+
+
+; HERE WE HAVE RESTED STRUCTURE ON THE TOP OF THE STACK
+
+ALOCOK:        MOVE    D,NOARGS(P)             ; GET NUMBER OF ARGS
+       CAIG    D,2                     ; SKIP IF NOT EXACTLY 3 ARGS
+       JRST    ALOCFX
+       GETYP   C,LNT-2(TP)             ; GET THE LENGTH ARGUMENT
+       CAIE    C,TFIX                  ; OK IF TYPE FIX
+       JRST    WRONGT
+       POP     P,C
+       SKIPL   A,LNT-1(TP)             ; GET LENGTH
+       JRST    @ALOCTB(C)              ; DO ALLOCATION
+       JRST    OUTRNG
+
+
+CPYVEC:        HLRE    A,OBJ+1(TP)             ; USE WHEN ONLY ONE ARG
+       MOVNS   A                       ; LENGTH ARG IS LENGTH OF STRUCTURE
+       ASH     A,-1                    ; # OF ELEMENTS FOR ALLOCATION
+       PUSH    TP,OBJ(TP)
+       SUB     P,[1,,1]
+       PUSH    TP,OBJ(TP)              ; REPUSH ARGS
+
+ALVEC: PUSH    P,A                     ; SAVE LENGTH
+       ASH     A,1
+       HRLI    A,(A)
+       ADD     A,(TP)
+       CAIL    A,-1                    ; CHK FOR OUT OF RANGE
+       JRST    OUTRNG
+       MOVE    D,NOARGS(P)
+       CAILE   D,3                     ; SKIP IF WE GET VECTOR
+       JRST    ALVEC2                  ; USER SUPPLIED VECTOR
+       MOVE    A,(P)
+       PUSHJ   P,IBLOK1
+ALVEC1:        MOVE    A,(P)                   ; # OF WORDS TO ALLOCATE
+       MOVE    C,B                     ; SAVE VECTOR POINTER
+       JUMPE   A,ALEVC4
+       ASH     A,1                     ; TIMES 2
+       HRLI    A,(A)
+       ADD     A,B                     ; PTING TO FIRST DOPE WORD -ALLOCATED 
+       CAIL    A,-1
+       JRST    OUTRNG
+       SUBI    A,1                     ; ptr to last element of the block
+       MOVE    D,NOARGS(P)
+       CAILE   D,3
+       CAMGE   B,(TP)          ; SKIP IF BACKWARDS BLT IS NEEDED
+       JRST    ALEVC3
+       HRRZ    0,(TP)
+       ADD     0,-4(TP)
+       ADD     0,-4(TP)        ; FIND END OF DEST
+       CAIGE   0,(B)           ; SEE IF BBLT IS NEEDED
+       JRST    ALEVC3
+       PUSHJ   P,BBLT          ; BLT IT
+       JRST    ALEVC4
+ALEVC3:        HRL     B,(TP)  ;bleft-ptr to source ,  b right -ptr to allocated space
+       BLT     B,(A)
+       MOVE    B,C
+ALEVC4:        MOVE    D,NOARGS(P)
+       CAIE    D,4
+       JRST    ALEVC5
+       MOVE    A,NOBJ-2(TP)
+       JRST    EXSUB
+ALEVC5:        MOVSI   A,TVEC
+       JRST    EXSUB
+
+; RESTED OBJECT ON TOP OF STACK
+
+ALVEC2:        GETYP   0,NOBJ-2(TP)            ; CHECK IT IS A VECTOR
+       CAIE    0,TARGS
+       CAIN    0,TVEC
+       SKIPA
+       JRST    WTYP
+       HLRE    A,NOBJ-1(TP)    ; CHECK SIZE
+       MOVNS   A
+       ASH     A,-1            ; # OF ELEMENTS
+       CAMGE   A,(P)           ; SKIP IF BIG ENOUGH
+       JRST    OUTRNG
+       MOVE    B,NOBJ-1(TP)    ; WINNER, JOIN COMMON CODE
+       JRST    ALVEC1
+
+CPYUVC:        HLRE    A,OBJ+1(TP)     ;# OF ELEMENTS FOR ALLOCATION
+       MOVNS   A
+       PUSH    TP,(B)
+       PUSH    TP,1(B)
+       SUB     P,[1,,1]
+
+
+ALUVEC:        PUSH    P,A
+       HRLI    A,(A)
+       ADD     A,(TP)                  ; PTING TO DOPE WORD OF ORIG VEC
+       CAIL    A,-1
+       JRST    OUTRNG
+       MOVE    D,NOARGS(P)
+       CAILE   D,3
+       JRST    ALUVE2
+       MOVE    A,(P)
+       PUSHJ   P,IBLOCK
+ALUVE1:        MOVE    A,(P)                   ; # of owrds to allocate
+       JUMPE   A,ALUEV4
+       HRLI    A,(A)
+       ADD     A,B                     ; LOCATION O FIRST ALLOCATED DOPE WORD
+       HLR     E,OBJ-1(TP)             ; # OF ELEMENTS IN UVECTOR
+       MOVNS   E
+       ADD     E,OBJ-1(TP)             ; LOCATION OF FIRST DOPE WORD FOR SOURCE
+       GETYP   E,(E)                   ; GET UTYPE
+       MOVE    D,NOARGS(P)
+       CAIE    D,4
+       PUTYP   E,(A)                   ; DUMP UTYPE INTO DOPE WORD OF ALLOC UVEC
+       CAILE   D,3
+       CAIN    0,(E)                   ; 0 HAS USER UVEC UTYPE
+       JRST    .+2
+       JRST    WRNGUT
+       CAIL    A,-1
+       JRST    OUTRNG
+       MOVE    D,NOARGS(P)
+       CAILE   D,3
+       CAMGE   B,(TP)                  ; SKIP IF NEEDS BACKWARDS BLT
+       JRST    ALUEV3
+       HRRZ    0,(TP)
+       ADD     0,-4(TP)
+       CAIGE   0,(B)
+       JRST    ALUEV3
+       SUBI    A,1
+       PUSHJ   P,BBLT
+       JRST    ALUEV4
+ALUEV3:        MOVE    C,B                     ; SAVE POINTER TO FINAL GUY
+       HRL     C,(TP)                  ; BUILD BLT POINTER
+       BLT     C,-1(A)
+ALUEV4:        MOVSI   A,TUVEC
+       JRST    EXSUB
+
+; BACKWARDS BLTTER
+; A==LAST WORD DEST (TP)==FIRST WORD DEST B==FIRST WORD SOURCE
+
+BBLT:  SUBI    A,-1(B)
+       MOVE    E,A             ; SAVE ADDITION
+       HRLZS   A               ; SWAP AND ZERO
+       HRR     A,(TP)
+       ADDI    A,-1(E)
+       MOVEI   C,(B)           ; SET UP DEST WORD
+       SUBI    C,(A)           ; CALC DIFF
+       ADDI    C,-1(E)         ; ADD TO GET TO END
+       HRLI    C,A             ; SET UP INDIRECT
+       POP     A,@C            ; BLT
+       TLNE    A,-1            ; SKIP IF DONE
+       JRST    .-2
+       POPJ    P,              ; EXIT
+
+ALUVE2:        GETYP   0,NOBJ-2(TP)    ; CHECK IT IS A VECTOR
+       CAIE    0,TUVEC
+       JRST    WTYP
+       HLRE    A,NOBJ-1(TP)            ; CHECK SIZE
+       MOVNS   A
+       CAMGE   A,(P)           ; SKIP IF BIG ENOUGH
+       JRST    OUTRNG
+       MOVE    B,NOBJ-1(TP)    ; WINNER, JOIN COMMON CODE
+       HLRE    A,B
+       SUBM    B,A
+       GETYP   0,(A)           ; GET UTYPE OF USER UVECTOR
+       JRST    ALUVE1
+
+ALBYT: MOVSI   C,TBYTE
+       JRST    ALSTRX
+
+CPYBYT:        SKIPA   C,$TBYTE
+CPYSTR:        MOVSI   C,TCHSTR
+       HRR     A,OBJ(TP)
+       PUSH    TP,(B)          ; ALSTR EXPECTS STRING IN TP
+       PUSH    TP,1(B)
+       SUB     P,[1,,1]
+       JRST    .+2
+
+ALSTR: MOVSI   C,TCHSTR
+ALSTRX:        PUSH    P,C             ; SAVE FINAL TYPE
+       PUSH    P,A             ; LENGTH
+       HRRZ    0,-1(TP)        ;0 IS LENGTH OFF VECTOR
+       CAIGE   0,(A)
+       JRST    OUTRNG
+       CAILE   D,3
+       JRST    ALSTR2
+       LDB     C,[300600,,(TP)]
+       MOVEI   B,36.
+       IDIVI   B,(C)           ; B BYT PER WD, C XTRA BITS
+       ADDI    A,-1(B)
+       IDIVI   A,(B)
+       PUSH    P,C
+       PUSHJ   P,IBLOCK        ;ALLOCATE SPACE
+       HLL     B,(TP)
+       POP     P,C
+       DPB     C,[360600,,B]
+       SUBI    B,1
+       MOVEM   B,-2(TP)
+       MOVE    A,(P)           ; # OF CHARS TO A
+       HLL     A,-1(P)
+       MOVEM   A,-3(TP)
+       JUMPN   A,SSTR1
+ALSTR9:        SUB     TP,[4,,4]
+       JRST    ALSTR8
+ALSTR1:        HLL     A,-2(P)         ; GET TYPE
+       HRRZ    C,B             ; SEE IF WE WILL OVERLAP
+       HRRZ    D,(TP)          ; GET RESTED STRING
+       CAIGE   C,(D)           ; IF C > B THE A CHANCE
+       JRST    SSTR
+       MOVEI   C,-1(TP)        ; GO TO BYTDOP
+       PUSHJ   P,BYTDOP
+       HRRZ    B,-2(TP)        ; IF B < A THEN OVERLAP
+       CAILE   B,(A)
+       JRST    SSTR
+       HRRZ    A,-4(TP)        ; GET LENGTH IN A
+       MOVEI   B,0             ; START LENGTH COUNT
+
+; ORIGINAL STRING IS ON THE TOP OF THE STACK
+
+CLOOP1:        INTGO
+       PUSH    P,[0]           ; STORE CHARS ON STACK
+       MOVSI   E,(<440000,,(P)>)       ; SETUP BYTE POINTER
+       LDB     0,[300600,,(TP)]
+       DPB     0,[300600,,E]
+CLOOP: IBP     E               ; BUMP IT
+       TRNE    E,-1            ; WORD FULL
+       AOJA    B,CLOOP1        ; PUSH NEW ONE
+       ILDB    0,(TP)          ; GET A CHARACTER
+       SOS     -1(TP)          ; DECREMENT CHARACTER COUNT
+       DPB     0,E
+       SOJN    A,CLOOP         ; ANY MORE?
+       SUB     TP,[2,,2]
+       MOVEI   C,(P)
+       PUSH    P,B             ; SAVE B
+       SUBI    C,(B)
+       MOVE    A,-2(TP)                ; GET COUNT
+       MOVE    B,(TP)
+       HRLI    C,440000        ; MAKE IT LOOK LIKE A BYTE PTR
+       LDB     0,[300600,,(TP)]
+       DPB     0,[300600,,C]
+CLOOP3:        ILDB    D,C             ; GET NEW CHARACTER
+       IDPB    D,B             ; DEPOSIT CHARACTER
+       SOJG    A,CLOOP3
+       POP     P,A
+       SUBI    P,(A)
+       HRLZS   A
+       SUB     P,A             ; CLEAN OFF STACK
+       POP     TP,B            ;BYTE PTR TO COPY
+       SUB     P,[1,,1]
+ALST10:        SUB     TP,[1,,1]       ; CLEAN OFF STACK
+ALSTR8:        POP     P,A             ;# FO ELEMENTS
+       HLL     A,(P)
+       SUB     TP,[6,,6]
+       JRST    EXSUB1
+
+
+; ROUTINE TO DO FAST TRANSFER FOR NON SHARING STRINGS
+
+SSTR:  MOVE    A,-4(TP)                ; GET # OF ELEMENTS INTO A
+       MOVE    B,-2(TP)
+SSTR1: POP     TP,C
+       SUB     TP,[1,,1]
+       HRRZS   A
+SSTR2: ILDB    D,C
+       IDPB    D,B
+       SOJG    A,SSTR2
+       POP     TP,B
+       JRST    ALST10
+
+ALSTR2:        GETYP   0,NOBJ-2(TP)    ; CHECK IT IS A VECTOR
+       MOVSS   0
+       CAME    0,-1(P)
+       JRST    WTYP
+       HRRZ    A,NOBJ-2(TP)
+       CAMGE   A,(P)           ; SKIP IF BIG ENOUGH
+       JRST    OUTRNG
+       EXCH    A,(P)
+       MOVE    B,NOBJ-1(TP)    ; WINNER, JOIN COMMON CODE
+       JUMPE   A,ALSTR9
+       JRST    ALSTR1
+
+; HERE TO COPY A LIST
+
+CPYLST:        SKIPN   OBJ+1(TP)
+       JRST    ZEROLT
+       PUSHJ   P,CELL2
+       POP     P,C
+       HRLI    C,TLIST         ; TP JUNK FOR GAR. COLLECTOR
+       PUSH    TP,C            ; TYPE
+       PUSH    TP,B            ; VALUE -PTR TO NEW LIST
+       PUSH    TP,C            ; TYPE
+       MOVE    C,OBJ-2(TP)     ; PTR TO FIRST ELEMENT OF ORIG. LIST
+REPLST:        MOVE    D,(C)
+       MOVE    E,1(C)          ; GET LIST ELEMENT INTO ALOC SPACE
+       HLLM    D,(B)
+       MOVEM   E,1(B)          ; PUT INTO ALLOCATED SPACE
+       HRRZ    C,(C)           ; UPDATE PTR
+       JUMPE   C,CLOSWL        ; END OF LIST?
+       PUSH    TP,B
+       PUSHJ   P,CELL2
+       POP     TP,D
+       HRRM    B,(D)           ; LINK ALLOCATED LIST CELLS
+       JRST    REPLST
+
+CLOSWL:        MOVE    A,-2(TP)        ; GET LIST
+       MOVE    B,-1(TP)
+       SUB     TP,[11.,,11.]
+LEXIT: SUB     P,[1,,1]
+       JRST    MPOPJ
+
+
+
+ALLIST:        PUSH    P,A
+       MOVE    D,NOARGS(P)
+       CAILE   D,3             ; SKIP IF WE BUILD LIST
+       JRST    CPYLS2
+       JUMPE   A,ZEROL1
+       ASH     A,1             ; TIMES 2
+       PUSHJ   P,CELL
+       POP     P,A             ; # OF ELEMENTS
+       PUSH    P,B             ; ptr to allocated list
+       POP     TP,C            ; ptr to orig list
+       JRST    ENTCOP
+
+COPYL: ADDI    B,2
+       HRRM    B,-2(B)         ; LINK ALOCATED LIST CELLS
+ENTCOP:        JUMPE   C,OUTRNG
+       MOVE    D,(C)   
+       MOVE    E,1(C)          ; get list element into D+E
+       HLLM    D,(B)
+       MOVEM   E,1(B)          ; put into allocated space
+       HRRZ    C,(C)           ; update ptrs
+       SOJG    A,COPYL         ; finish transfer?
+
+CLOSEL:        POP     P,B
+       MOVE    A,(TP)
+       SUB     TP,[9.,,9.]
+       JRST    LEXIT
+
+
+ZEROL1:        SUB     TP,[2,,2]
+ZEROLT:        MOVSI   A,TLIST
+       MOVEI   B,0
+       SUB     TP,[8,,8]
+       JRST    EXSUB1
+
+CPYLS2:        GETYP   0,NOBJ-2(TP)
+       CAIE    0,TLIST
+       JRST    WTYP
+       MOVE    B,NOBJ-1(TP)            ; GET DEST LIST
+       MOVE    C,(TP)
+
+       JUMPE   A,CPYLS3
+CPYLS4:        JUMPE   B,OUTRNG
+       JUMPE   C,OUTRNG
+       MOVE    D,1(C)
+       MOVEM   D,1(B)
+       GETYP   0,(C)
+       HRLM    0,(B)
+       HRRZ    B,(B)
+       HRRZ    C,(C)
+       SOJG    A,CPYLS4
+
+CPYLS3:        MOVE    D,-2(TP)
+       MOVE    B,NOBJ-1(TP)
+       MOVSI   A,TLIST
+
+; HERE TO EXIT
+
+EXSUB: SUB     TP,[10.,,10.]
+EXSUB1:        SUB     P,[2,,2]
+       JRST    MPOPJ
+
+
+\f
+; PROCESS TYPE ILLEGAL
+
+ILLCHO:        HRRZ    B,1(B)  ;GET CLOBBERED TYPE
+       CAIN    B,TARGS ;WAS IT ARGS?
+       JRST    ILLAR1
+       CAIN    B,TFRAME                ;A FRAME?
+       JRST    ILFRAM
+       CAIN    B,TLOCD         ;A LOCATIVE TO AN ID
+       JRST    ILLOC1
+
+       LSH     B,1             ;NONE OF ABOVE LOOK IN TABLE
+       ADDI    B,TYPVEC+1
+       PUSH    TP,$TATOM
+       PUSH    TP,EQUOTE ILLEGAL
+       PUSH    TP,$TATOM
+       PUSH    TP,(B)          ;PUSH ATOMIC NAME
+       MOVEI   A,2
+       JRST    CALER           ;GO TO ERROR REPORTER
+
+; CHECK AN ARGS POINTER
+
+CHARGS:        PUSHJ   P,ICHARG                ; INTERNAL CHECK
+       JUMPN   B,CPOPJ
+
+ILLAR1:        ERRUUO  EQUOTE ILLEGAL-ARGUMENT-BLOCK
+
+ICHARG:        PUSH    P,A             ;SAVE SOME ACS
+       PUSH    P,B
+       PUSH    P,C
+       SKIPN   C,1(B)  ;GET POINTER
+       JRST    ILLARG          ; ZERO POINTER IS ILLEGAL
+       HLRE    A,C             ;FIND ASSOCIATED FRAME
+       SUBI    C,(A)           ;C POINTS TO FRAME OR FRAME POINTER
+       GETYP   A,(C)           ;GET TYPE OF NEXT GOODIE
+       CAIN    A,TCBLK
+       JRST    CHARG1
+       CAIE    A,TENTRY        ;MUST BE EITHER ENTRY OR TINFO
+       CAIN    A,TINFO
+       JRST    CHARG1          ;WINNER
+       JRST    ILLARG
+
+CHARG1:        CAIN    A,TINFO         ;POINTER TO FRAME?
+       ADD     C,1(C)          ;YES, GET IT
+       CAIE    A,TINFO         ;POINTS TO ENTRT?
+       MOVEI   C,FRAMLN(C)     ;YES POINT TO END OF FRAME
+       HLRZ    C,OTBSAV(C)     ;GET TIME FROM FRAME
+       HRRZ    B,(B)           ;AND ARGS TIME
+       CAIE    B,(C)           ;SAME?
+ILLARG:        SETZM   -1(P)           ; RETURN ZEROED B
+POPBCJ:        POP     P,C
+       POP     P,B
+       POP     P,A
+       POPJ    P,              ;GO GET PRIM TYPE
+\f
+
+
+; CHECK A FRAME POINTER
+
+CHFRM: PUSHJ   P,CHFRAM
+       JUMPN   B,CPOPJ
+
+ILFRAM:        ERRUUO  EQUOTE ILLEGAL-FRAME
+
+CHFRAM:        PUSH    P,A             ;SAVE SOME REGISTERS
+       PUSH    P,B
+       PUSH    P,C
+       HRRZ    A,(B)           ; GE PVP POINTER
+       HLRZ    C,(A)           ; GET LNTH
+       SUBI    A,-1(C)         ; POINT TO TOP
+       MOVE    PVP,PVSTOR+1
+       CAIN    A,(PVP)         ; SKIP  IF NOT THIS PROCESS
+       MOVEM   TP,TPSTO+1(A)   ; MAKE CURRENT BE STORED
+       HRRZ    A,TPSTO+1(A)    ; GET TP FOR THIS PROC
+       HRRZ    C,1(B)          ;GET POINTER PART
+       CAILE   C,1(A)          ;STILL WITHIN STACK
+       JRST    BDFR
+       HLRZ    A,FSAV(C)       ;CHECK STILL AN ENTRY BLOCK
+       CAIN    A,TCBLK
+       JRST    .+3
+       CAIE    A,TENTRY
+       JRST    BDFR
+       HLRZ    A,1(B)          ;GET TIME FROM POINTER
+       HLRZ    C,OTBSAV(C)     ;AND FROM FRAME
+       CAIE    A,(C)           ;SAME?
+BDFR:  SETZM   -1(P)           ; RETURN 0 IN B
+       JRST    POPBCJ          ;YES, WIN
+
+; CHECK A LOCATIVE TO AN IDENTIFIER
+
+CHLOCI:        PUSHJ   P,ICHLOC
+       JUMPN   B,CPOPJ
+
+ILLOC1:        ERRUUO  EQUOTE ILLEGAL-LOCATIVE
+
+ICHLOC:        PUSH    P,A
+       PUSH    P,B
+       PUSH    P,C
+
+       HRRZ    A,(B)           ;GET TIME FROM POINTER
+       JUMPE   A,POPBCJ        ;ZERO, GLOBAL VARIABLE NO TIME
+       HRRZ    C,1(B)          ;POINT TO STACK
+       CAMLE   C,VECTOP
+       JRST    ILLOC           ;NO
+       HRRZ    C,2(C)          ; SHOULD BE DECL,,TIME
+       CAIE    A,(C)
+ILLOC: SETZM   -1(P)           ; RET 0 IN B
+       JRST    POPBCJ
+
+
+       
+\f
+; PREDICATE TO SEE IF AN OBJECT IS STRUCTURED
+
+MFUNCTION %STRUC,SUBR,[STRUCTURED?]
+
+       ENTRY   1
+
+       GETYP   A,(AB)          ; GET TYPE
+       PUSHJ   P,ISTRUC        ; INTERNAL
+       JRST    IFALSE
+       JRST    ITRUTH
+
+
+; PREDICATE TO CHECK THE LEGALITY OF A FRAME/ARGS TUPLE/IDENTIFIER LOCATIVE
+
+MFUNCTION %LEGAL,SUBR,[LEGAL?]
+
+       ENTRY   1
+
+       MOVEI   B,(AB)          ; POINT TO ARG
+       PUSHJ   P,ILEGQ
+       JRST    IFALSE
+       JRST    ITRUTH
+
+ILEGQ: GETYP   A,(B)
+       CAIN    A,TILLEG
+       POPJ    P,
+       PUSHJ   P,SAT           ; GET STORG TYPE
+       CAIN    A,SFRAME        ; FRAME?
+       PUSHJ   P,CHFRAM
+       CAIE    A,SLOCA
+       CAIN    A,SARGS         ; ARG TUPLE
+       PUSHJ   P,ICHARG
+       CAIN    A,SLOCID        ; ID LOCATIVE
+       PUSHJ   P,ICHLOC
+       JUMPE   B,CPOPJ
+       JRST    CPOPJ1
+
+
+; COMPILERS CALL
+
+CILEGQ:        PUSH    TP,A
+       PUSH    TP,B
+       MOVEI   B,-1(TP)
+       PUSHJ   P,ILEGQ
+       TDZA    0,0
+       MOVEI   0,1
+       SUB     TP,[2,,2]
+       JUMPE   0,NO
+
+YES:   MOVSI   A,TATOM
+       MOVE    B,IMQUOTE T
+       JRST    CPOPJ1
+
+NOM:   SUBM    M,(P)
+NO:    MOVSI   A,TFALSE
+       MOVEI   B,0
+       POPJ    P,
+
+YESM:  SUBM    M,(P)
+       JRST    YES
+\f;SUBRS TO DEFINE, GET, AND PUT BIT FIELDS
+
+MFUNCTION BITS,SUBR
+       ENTRY
+       JUMPGE  AB,TFA          ;AT LEAST ONE ARG ?
+       GETYP   A,(AB)
+       CAIE    A,TFIX
+       JRST    WTYP1
+       SKIPLE  C,(AB)+1        ;GET FIRST AND CHECK TO SEE IF POSITIVE
+       CAILE   C,44            ;CHECK IF FIELD NOT GREATER THAN WORD SIZE
+       JRST    OUTRNG
+       MOVEI   B,0
+       CAML    AB,[-2,,0]      ;ONLY ONE ARG ?
+       JRST    ONEF            ;YES
+       CAMGE   AB,[-4,,0]      ;MORE THAN TWO ARGS ?
+       JRST    TMA             ;YES, LOSE
+       GETYP   A,(AB)+2
+       CAIE    A,TFIX
+       JRST    WTYP2
+       SKIPGE  B,(AB)+3        ;GET SECOND ARG AND CHECK TO SEE IF NON-NEGATIVE
+       JRST    OUTRNG
+       ADD     C,(AB)+3        ;CALCULATE LEFTMOST EXTENT OF THE FIELD
+       CAILE   C,44            ;SHOULD BE LESS THAN WORD SIZE
+       JRST    OUTRNG
+       LSH     B,6
+ONEF:  ADD     B,(AB)+1
+       LSH     B,30            ;FORM BYTE POINTER'S LEFT HALF
+       MOVSI   A,TBITS
+       JRST    FINIS
+
+
+
+MFUNCTION GETBITS,SUBR
+       ENTRY 2
+       GETYP   A,(AB)
+       PUSHJ   P,SAT
+       CAIN    A,SSTORE
+       JRST    .+3
+       CAIE    A,S1WORD
+       JRST    WTYP1
+       GETYP   A,(AB)+2
+       CAIE    A,TBITS
+       JRST    WTYP2
+       MOVEI   A,(AB)+1        ;GET ADDRESS OF THE WORD
+       HLL     A,(AB)+3        ;GET LEFT HALF OF BYTE POINTER
+       LDB     B,A
+       MOVSI   A,TWORD         ; ALWAYS RETURN WORD\b\b\b\b____
+       JRST    FINIS
+
+
+MFUNCTION PUTBITS,SUBR
+       ENTRY
+       CAML    AB,[-2,,0]      ;AT LEAST TWO ARGS ?
+       JRST    TFA             ;NO, LOSE
+       GETYP   A,(AB)
+       PUSHJ   P,SAT
+       CAIE    A,S1WORD
+       JRST    WTYP1
+       GETYP   A,(AB)+2
+       CAIE    A,TBITS
+       JRST    WTYP2
+       MOVEI   B,0             ;EMPTY THIRD ARG DEFAULT
+       CAML    AB,[-4,,0]      ;ONLY TWO ARGS ?
+       JRST    TWOF
+       CAMGE   AB,[-6,,0]      ;MORE THAN THREE ARGS ?
+       JRST    TMA             ;YES, LOSE
+       GETYP   A,(AB)+4
+       PUSHJ   P,SAT
+       CAIE    A,S1WORD
+       JRST    WTYP3
+       MOVE    B,(AB)+5
+TWOF:  MOVEI   A,(AB)+1        ;ADDRESS OF THE TARGET WORD
+       HLL     A,(AB)+3        ;GET THE LEFT HALF OF THE BYTE POINTER
+       DPB     B,A
+       MOVE    B,(AB)+1
+       MOVE    A,(AB)          ;SAME TYPE AS FIRST ARG'S
+       JRST    FINIS
+\f
+
+; FUNCTION TO GET THE LENGTH OF LISTS,VECTORS AND CHAR STRINGS
+
+MFUNCTION      LNTHQ,SUBR,[LENGTH?]
+
+       ENTRY 2
+       GETYP   A,(AB)2
+       CAIE    A,TFIX
+       JRST    WTYP2
+       PUSH    P,(AB)3
+       JRST    LNTHER
+
+
+MFUNCTION LENGTH,SUBR
+
+       ENTRY   1
+       PUSH    P,[377777777777]
+LNTHER:        MOVE    B,AB            ;POINT TO ARGS
+       PUSHJ   P,PTYPE         ;GET ITS PRIM TYPE
+       MOVE    B,1(AB)
+       MOVE    C,(AB)
+       PUSHJ   P,@LENTBL(A)    ; CALL RIGTH ONE
+       JRST    LFINIS          ;OTHERWISE USE 0
+
+PRDISP LENTBL,IWTYP1,[[P2WORD,LNLST],[P2NWORD,LNVEC],[PNWORD,LNUVEC]
+[PARGS,LNVEC],[PCHSTR,LNCHAR],[PTMPLT,LNTMPL],[PBYTE,LNCHAR]]
+
+LNLST: SKIPN   C,B             ; EMPTY?
+       JRST    LNLST2          ; YUP, LEAVE
+       MOVEI   B,1             ; INIT COUNTER
+       MOVSI   A,TLIST         ;WILL BECOME INTERRUPTABLE
+       MOVE    PVP,PVSTOR+1
+       HLLM    A,CSTO(PVP)     ;AND C WILL BE A LIST POINTER
+LNLST1:        INTGO           ;IN CASE CIRCULAR LIST
+       CAMLE   B,(P)-1
+       JRST    LNLST2
+       HRRZ    C,(C)           ;STEP
+       JUMPE   C,.+2           ;DONE, RETRUN LENGTH
+       AOJA    B,LNLST1        ;COUNT AND GO
+LNLST2:        MOVE    PVP,PVSTOR+1
+       SETZM   CSTO(PVP)
+       POPJ    P,
+
+LFINIS:        POP     P,C
+       CAMLE   B,C
+       JRST    IFALSE
+       MOVSI   A,TFIX          ;LENGTH IS AN INTEGER
+       JRST    FINIS
+
+LNVEC: ASH     B,-1            ;GENERAL VECTOR DIVIDE BY 2
+LNUVEC:        HLRES   B               ;GET LENGTH
+       MOVMS   B               ;MAKE POS
+       POPJ    P,
+
+LNCHAR:        HRRZ    B,C             ; GET COUNT
+       POPJ    P,
+
+LNTMPL:        GETYP   A,(B)           ; GET REAL SAT
+       SUBI    A,NUMSAT+1
+       HRLS    A               ; READY TO HIT TABLE
+       ADD     A,TD.LNT+1
+       JUMPGE  A,BADTPL
+       MOVE    C,B             ; DATUM TO C
+       XCT     (A)             ; GET LENGTH
+       HLRZS   C               ; REST COUNTER
+       SUBI    B,(C)           ; FLUSH IT OFF
+       MOVEI   B,(B)           ; IN CASE FUNNY STUFF
+       MOVSI   A,TFIX
+       POPJ    P,
+
+; COMPILERS ENTRIES
+
+CILNT: SUBM    M,(P)
+       PUSH    P,[377777,,-1]
+       MOVE    C,A
+       GETYP   A,A
+       PUSHJ   P,CPTYPE        ; GET PRIMTYPE
+       JUMPE   A,CILN1
+       PUSHJ   P,@LENTBL(A)    ; DISPATCH
+       MOVSI   A,TFIX
+CILN2: SUB     P,[1,,1]
+MPOPJ: SUBM    M,(P)
+       POPJ    P,
+
+CILN1: PUSH    TP,C
+       PUSH    TP,B
+       MCALL   1,LENGTH
+       JRST    CILN2
+
+CILNQ: SUBM    M,(P)
+       PUSH    P,C
+       MOVE    C,A
+       GETYP   A,A
+       PUSHJ   P,CPTYPE
+       JUMPE   A,CILNQ1
+       PUSHJ   P,@LENTBL(A)
+       POP     P,C
+       SUBM    M,(P)
+       MOVSI   A,TFIX
+       CAMG    B,C
+       JRST    CPOPJ1
+       MOVSI   A,TFALSE
+       MOVEI   B,0
+       POPJ    P,
+
+CILNQ1:        PUSH    TP,C
+       PUSH    TP,B
+       PUSH    TP,$TFIX
+       PUSH    TP,(P)
+       MCALL   2,LENGTH?
+       SUBM    M,(P)
+       GETYP   0,A
+       CAIE    0,TFALSE
+       AOS     (P)
+       POPJ    P,
+\f
+
+MFUNCTION BYTSIZ,SUBR,[BYTE-SIZE]
+
+       ENTRY   1
+
+       GETYP   A,(AB)
+       PUSHJ   P,SAT
+       CAIE    A,SBYTE
+        JRST   WTYP1
+       LDB     B,[300600,,1(AB)]
+       MOVSI   A,TFIX
+       JRST    FINIS
+\f
+
+
+IDNT1: MOVE    A,(AB)          ;RETURN THE FIRST ARG
+       MOVE    B,1(AB)
+       JRST    FINIS
+
+IMFUNCTION QUOTE,FSUBR
+
+       ENTRY   1
+
+       GETYP   A,(AB)
+       CAIE    A,TLIST         ;ARG MUST BE A LIST
+       JRST    WTYP1
+       SKIPN   B,1(AB)         ;SHOULD HAVE A BODY
+       JRST    TFA
+
+       HLLZ    A,(B)           ; GET IT
+       MOVE    B,1(B)
+       JSP     E,CHKAB
+       JRST    FINIS
+
+MFUNCTION      NEQ,SUBR,[N==?]
+       
+       MOVEI   D,1
+       JRST    EQR
+
+MFUNCTION EQ,SUBR,[==?]
+
+       MOVEI   D,0
+EQR:   ENTRY   2
+
+       GETYP   A,(AB)          ;GET 1ST TYPE
+       GETYP   C,2(AB)         ;AND 2D TYPE
+       MOVE    B,1(AB)
+       CAIN    A,(C)           ;CHECK IT
+       CAME    B,3(AB)
+       JRST    @TABLE2(D)
+       JRST    @TABLE1(D)
+
+ITRUTH:        MOVSI   A,TATOM         ;RETURN TRUTH
+       MOVE    B,IMQUOTE T
+       JRST    FINIS
+
+IFALSE:        MOVSI   A,TFALSE                ;RETURN FALSE
+       MOVEI   B,0
+       JRST    FINIS
+
+TABLE1:        ITRUTH
+TABLE2:        IFALSE
+       ITRUTH
+
+\f
+
+
+MFUNCTION EMPTY,SUBR,EMPTY?
+
+       ENTRY   1
+
+       MOVE    B,AB
+       PUSHJ   P,PTYPE         ;GET PRIMITIVE TYPE
+
+       MOVEI   A,(A)
+       JUMPE   A,WTYP1
+       SKIPN   B,1(AB)         ;GET THE ARG
+       JRST    ITRUTH
+
+       CAIN    A,PTMPLT        ; TEMPLATE?
+       JRST    EMPTPL
+       CAIE    A,P2WORD                ;A LIST?
+       JRST    EMPT1           ;NO VECTOR OR CHSTR
+       JUMPE   B,ITRUTH                ;0 POINTER MEANS EMPTY LIST
+       JRST    IFALSE
+
+
+EMPT1: CAIN    A,PBYTE
+       JRST    .+3
+       CAIE    A,PCHSTR                ;CHAR STRING?
+       JRST    EMPT2           ;NO, VECTOR
+       HRRZ    B,(AB)          ; GET COUNT
+       JUMPE   B,ITRUTH        ;0 STRING WINS
+       JRST    IFALSE
+
+EMPT2: JUMPGE  B,ITRUTH
+       JRST    IFALSE
+
+EMPTPL:        PUSHJ   P,LNTMPL        ; GET LENGTH
+       JUMPE   B,ITRUTH
+       JRST    IFALSE
+
+; COMPILER'S ENTRY TO EMPTY
+
+CEMPTY:        PUSH    P,A
+       GETYP   A,A
+       PUSHJ   P,CPTYPE
+       POP     P,0
+       JUMPE   A,CEMPT2
+       JUMPE   B,YES           ; ALWAYS EMPTY
+       CAIN    A,PTMPLT
+       JRST    CEMPTP
+       CAIN    A,P2WORD
+       JRST    NO
+       CAIN    A,PCHSTR
+       JRST    .+3
+       JUMPGE  B,YES
+       JRST    NO
+       TRNE    0,-1            ; STRING, SKIP ON ZERO LENGTH FIELD
+       JRST    NO
+       JRST    YES
+
+CEMPTP:        PUSHJ   P,LNTMPL
+       JUMPE   B,YES
+       JRST    NO
+
+CEMPT2:        PUSH    TP,0
+       PUSH    TP,B
+       MCALL   1,EMPTY?
+       JUMPE   B,NO
+       JRST    YES
+
+MFUNCTION      NEQUAL,SUBR,[N=?]
+       PUSH    P,[1]
+       JRST    EQUALR
+
+MFUNCTION EQUAL,SUBR,[=?]
+       PUSH    P,[0]
+EQUALR:        ENTRY   2
+
+       MOVE    C,AB            ;SET UP TO CALL INTERNAL
+       MOVE    D,AB
+       ADD     D,[2,,2]        ;C POINTS TO FIRS, D TO SECOND
+       PUSHJ   P,IEQUAL        ;CALL INTERNAL
+       JRST    EQFALS          ;NO SKIP MEANS LOSE
+       JRST    EQTRUE
+EQFALS:        POP     P,C
+       JRST    @TABLE2(C)
+EQTRUE:        POP     P,C
+       JRST    @TABLE1(C)
+
+\f
+; COMPILER'S ENTRY TO =? AND N=?
+
+CINEQU:        PUSH    P,[0]
+       JRST    .+2
+
+CIEQUA:        PUSH    P,[1]
+       PUSH    TP,A
+       PUSH    TP,B
+       PUSH    TP,C
+       PUSH    TP,D
+       MOVEI   C,-3(TP)
+       MOVEI   D,-1(TP)
+       SUBM    M,-1(P)         ; MAY BECOME INTERRUPTABLE
+       PUSHJ   P,IEQUAL
+       JRST    NOE
+       POP     P,C
+       SUB     TP,[4,,4]       ; FLUSH TEMPS
+       JRST    @CTAB1(C)
+
+NOE:   POP     P,C
+       SUB     TP,[4,,4]
+       JRST    @CTAB2(C)
+
+CTAB1: SETZ    NOM
+CTAB2: SETZ    YESM
+       SETZ    NOM
+       
+; INTERNAL EQUAL SUBROUTINE
+
+IEQUAL:        MOVE    B,C             ;NOW CHECK THE ARGS
+       PUSHJ   P,PTYPE
+       MOVE    B,D
+       PUSHJ   P,PTYPE
+       MOVE    F,0             ; SAVE SAT FOR OFFSET HACK
+       GETYP   0,(C)           ;NOW CHECK FOR EQ
+       GETYP   B,(D)
+       MOVE    E,1(C)
+       CAIN    0,(B)           ;DONT SKIP IF POSSIBLE WINNER
+       CAME    E,1(D)          ;DEFINITE WINNER, SKIP
+       JRST    IEQ1
+CPOPJ1:        AOS     (P)             ;EQ, SKIP RETURN
+       POPJ    P,
+
+
+IEQ1:  CAIE    0,(B)           ;SKIP IF POSSIBLE MATCH
+CPOPJ: POPJ    P,              ;NOT POSSIBLE WINNERS
+       CAIN    F,SOFFS
+       JRST    EQOFFS
+       JRST    @EQTBL(A)       ;DISPATCH
+
+PRDISP EQTBL,CPOPJ,[[P2WORD,EQLIST],[P2NWORD,EQVEC],[PNWORD,EQUVEC]
+[PARGS,EQVEC],[PCHSTR,EQCHST],[PTMPLT,EQTMPL],[PBYTE,EQCHST]]
+
+EQLIST:        PUSHJ   P,PUSHCD        ;PUT ARGS ON STACK
+
+EQLST1:        INTGO                   ;IN CASE OF CIRCULAR
+       HRRZ    C,-2(TP)        ;GET FIRST
+       HRRZ    D,(TP)          ;AND 2D
+       CAIN    C,(D)           ;EQUAL?
+       JRST    EQLST2          ;YES, LEAVE
+       JUMPE   C,EQLST3        ;NIL LOSES
+       JUMPE   D,EQLST3
+       GETYP   0,(C)           ;CHECK DEFERMENT
+       CAIN    0,TDEFER
+       HRRZ    C,1(C)          ;PICK UP POINTED TO CROCK
+       GETYP   0,(D)
+       CAIN    0,TDEFER
+       HRRZ    D,1(D)          ;POINT TO REAL GOODIE
+       PUSHJ   P,IEQUAL        ;CHECK THE CARS
+       JRST    EQLST3          ;LOSE
+       HRRZ    C,@-2(TP)       ;CDR THE LISTS
+       HRRZ    D,@(TP)
+       HRRZM   C,-2(TP)        ;AND STORE
+       HRRZM   D,(TP)
+       JRST    EQLST1
+
+EQLST2:        AOS     (P)             ;SKIP RETRUN
+EQLST3:        SUB     TP,[4,,4]       ;REMOVE CRUFT
+       POPJ    P,
+\f
+; HERE FOR HACKING OFFSETS
+EQOFFS:        HRRZ    A,1(C)
+       HRRZ    B,1(D)          ; GET NUMBERS
+       CAIE    A,(B)           ; POSSIBLE WINNER IF SKIP
+        POPJ   P,
+       PUSH    TP,$TLIST
+       HLRZ    A,1(C)
+       PUSH    TP,A
+       PUSH    TP,$TLIST
+       HLRZ    A,1(D)
+       PUSH    TP,A
+       JRST    EQLST1          ; SEE IF THE TWO LISTS ARE EQUAL
+
+; HERE FOR HACKING TEMPLATE STRUCTURES
+
+EQTMPL:        PUSHJ   P,PUSHCD        ; SAVE GOODIES
+       PUSHJ   P,PUSHCD
+       MOVE    C,1(C)          ; CHECK REAL SATS
+       GETYP   C,(C)
+       MOVE    D,1(D)
+       GETYP   0,(D)
+       CAIE    0,(C)           ; SKIP IF WINNERS
+       JRST    EQTMP4
+       PUSH    P,0             ; SAVE MAGIC OFFSET
+       MOVE    B,-2(TP)
+       PUSHJ   P,TM.LN1        ; RET LENGTH IN B
+       MOVEI   B,(B)           ; FLUSH FUNNY
+       HLRZ    C,-2(TP)
+       SUBI    B,(C)
+       PUSH    P,B
+       MOVE    C,(TP)          ; POINTER TO OTHER GUY
+       ADD     A,TD.LNT+1
+       XCT     (A)             ; OTHER LENGTH TO B
+       HLRZ    0,-2(TP)        ; REST OFFSETTER
+       SUBI    0,1
+       PUSH    P,0
+       MOVEI   B,(B)
+       HLRZ    C,(TP)
+       SUBI    B,(C)
+       HRRZS   -4(TP)          ; UNDO RESTING (ACCOUNTED FOR BY STARTING
+                               ;  AT LATER ELEMENT)
+       HRRZS   -6(TP)
+       CAME    B,-1(P)
+       JRST    EQTMP1
+
+EQTMP2:        AOS     C,(P)
+       SOSGE   -1(P)
+       JRST    EQTMP3          ; WIN!!
+
+       MOVE    B,-6(TP)        ; POINTER
+       MOVE    0,-2(P)         ; GET MAGIC OFFSET
+       PUSHJ   P,TMPLNT        ; GET AN ELEMENT
+       MOVEM   A,-3(TP)
+       MOVEM   B,-2(TP)
+       MOVE    C,(P)
+       MOVE    B,-4(TP)        ; OTHER GUY
+       MOVE    0,-2(P)
+       PUSHJ   P,TMPLNT
+       MOVEM   A,-1(TP)
+       MOVEM   B,(TP)
+       MOVEI   C,-3(TP)
+       MOVEI   D,-1(TP)
+       PUSHJ   P,IEQUAL        ; RECURSE
+       JRST    EQTMP1          ; LOSER
+       JRST    EQTMP2          ; WINNER
+
+EQTMP3:        AOS     -3(P)           ; WIN RETURN
+EQTMP1:        SUB     P,[3,,3]        ; FLUSH JUNK
+EQTMP4:        SUB     TP,[10,,10]
+       POPJ    P,
+
+
+
+EQVEC: HLRE    A,1(C)          ;GET LENGTHS
+       HLRZ    B,1(D)
+       CAIE    B,(A)           ;SKIP IF EQUAL LENGTHS
+       POPJ    P,              ;LOSE
+       JUMPGE  A,CPOPJ1        ;SKIP RETRUN WIN
+       PUSHJ   P,PUSHCD        ;SAVE ARGS
+
+EQVEC1:        INTGO                   ;IN CASE LONG VECTOR
+       MOVE    C,(TP)
+       MOVE    D,-2(TP)        ;ARGS TO C AND D
+       PUSHJ   P,IEQUAL
+       JRST    EQLST3
+       MOVE    C,[2,,2]        ;GET BUMPER
+       ADDM    C,(TP)
+       ADDB    C,-2(TP)        ;BUMP BOTH POINTERS
+       JUMPL   C,EQVEC1
+       JRST    EQLST2
+
+EQUVEC:        HLRE    A,1(C)          ;GET LENGTHS
+       HLRZ    B,1(D)
+       CAIE    B,(A)           ;SKIP IF EQUAL
+       POPJ    P,
+
+       HRRZ    B,1(C)          ;START COMPUTING DOPE WORD LOCN
+       SUB     B,A             ;B POINTS TO DOPE WORD
+       GETYP   0,(B)           ;GET UNIFORM TYPE
+       HRRZ    B,1(D)          ;NOW FIND OTHER DOPE WORD
+       SUB     B,A
+       GETYP   B,(B)           ;OTHER UNIFORM TYPE
+       CAIE    0,(B)           ;TYPES THE SAME?
+       POPJ    P,              ;NO, LOSE
+
+       JUMPGE  A,CPOPJ1        ;IF ZERO LENGTH ALREADY WON
+
+       HRLZI   B,(B)           ;TYPE TO LH
+       PUSH    P,B             ;AND SAVED
+       PUSHJ   P,PUSHCD        ;SAVE ARGS
+
+EQUV1: MOVEI   C,1(TP)         ;POINT TO WHERE WILL GO
+       PUSH    TP,(P)
+       MOVE    A,-3(TP)        ;PUSH ONE OF THE VECTORS
+       PUSH    TP,(A)          ; PUSH ELEMENT
+       MOVEI   D,1(TP)         ;POINT TO 2D ARG
+       PUSH    TP,(P)
+       MOVE    A,-3(TP)        ;AND PUSH ITS POINTER
+       PUSH    TP,(A)
+       PUSHJ   P,IEQUAL
+       JRST    UNEQUV
+
+       SUB     TP,[4,,4]       ;POP TP
+       MOVE    A,[1,,1]
+       ADDM    A,(TP)          ;BUMP POINTERS
+       ADDB    A,-2(TP)
+       JUMPL   A,EQUV1         ;JUMP IF STILL MORE STUFF
+       SUB     P,[1,,1]        ;POP OFF TYPE
+       JRST    EQLST2
+
+UNEQUV:        SUB     P,[1,,1]
+       SUB     TP,[10,,10]
+       POPJ    P,
+\f
+
+
+EQCHST:        HRRZ    B,(C)           ; GET LENGTHS
+       HRRZ    A,(D)
+       CAIE    A,(B)           ;SAME
+       JRST    EQCHS3          ;NO, LOSE
+       LDB     0,[300600,,1(C)]
+       LDB     E,[300600,,1(D)]
+       CAIE    0,(E)
+       JRST    EQCHS3
+       MOVE    C,1(C)
+       MOVE    D,1(D)
+       JUMPE   A,EQCHS4        ;BOTH 0 LENGTH, WINS
+
+EQCHS2:
+       ILDB    0,C             ;GET NEXT CHARS
+       ILDB    E,D
+       CAME    0,E             ; SKIP IF STILL WINNING
+       JRST    EQCHS3          ; NOT =
+       SOJG    A,EQCHS2
+
+EQCHS4:        AOS     (P)
+EQCHS3:        POPJ    P,
+
+PUSHCD:        PUSH    TP,(C)
+       PUSH    TP,1(C)
+       PUSH    TP,(D)
+       PUSH    TP,1(D)
+       POPJ    P,
+
+\f
+; REST/NTH/AT/PUT/GET
+
+; ARG CHECKER
+
+ARGS1: MOVE    E,[JRST WTYP2]  ; ERROR CONDITION FOR 2D ARG NOT FIXED
+ARGS2: HLRE    0,AB            ; CHECK NO. OF ARGS
+       ASH     0,-1            ; TO - NO. OF ARGS
+       AOJG    0,TFA           ; 0--TOO FEW
+       AOJL    0,TMA           ; MORE THAT 2-- TOO MANY
+       MOVEI   C,1             ; DEFAULT ARG2
+       JUMPN   0,ARGS4         ; GET STRUCTURED ARG
+ARGS3: GETYP   A,2(AB)
+       CAIN    A,TOFFS         ; OFFSET?
+        JRST   ARGOFF          ; GO DO DECL-CHECK AND SUCH
+       CAIE    A,TFIX          ; SHOULD BE FIXED NUMBER
+       XCT     E               ; DO ERROR THING
+       SKIPGE  C,3(AB)         ; BETTER BE NON-NEGATIVE
+       JRST    OUTRNG
+ARGS4: MOVEI   B,(AB)          ; POINT TO STRUCTURED POINTER
+       PUSHJ   P,PTYPE         ; GET PRIM TYPE
+       MOVEI   E,(A)           ; DISPATCH CODE TO E
+       MOVE    A,(AB)          ; GET ARG 1
+       MOVE    B,1(AB)
+       POPJ    P,
+ARGOFF:        HLRZ    B,3(AB)         ; PICK UP DECL POINTER FOR OFFSET
+       JUMPE   B,ARGOF1
+       MOVE    A,(B)           ; TYPE WORD
+       MOVE    B,1(B)          ; VALUE
+       MOVE    C,(AB)
+       MOVE    D,1(AB)
+       PUSHJ   P,TMATCH        ; CHECK THE DECL
+        JRST   WTYP1           ; FIRST ARG WRONG TYPE
+ARGOF1:        HRRE    C,3(AB)         ; GET THE FIX
+       JUMPL   C,OUTRNG
+       JRST    ARGS4           ; FINISH
+
+; REST 
+
+IMFUNCTION REST,SUBR
+
+       ENTRY
+       PUSHJ   P,ARGS1         ; GET AND CHECK ARGS
+       PUSHJ   P,@RESTBL(E)    ; DO IT BASED ON TYPE
+       MOVE    C,A             ; THE FOLLOWING IS TO MAKE STORAGE WORK
+       GETYP   A,(AB)
+       PUSHJ   P,SAT
+       CAIN    A,SSTORE        ; SKIP IF NOT STORAGE
+       MOVSI   C,TSTORA        ; USE ITS PRIMTYPE
+       MOVE    A,C
+       JRST    FINIS
+
+PRDISP RESTBL,IWTYP1,[[P2WORD,LREST],[PNWORD,UREST],[P2NWOR,VREST],[PARGS,AREST]
+[PCHSTR,SREST],[PTMPLT,TMPRST],[PBYTE,BREST]]
+
+; AT
+
+MFUNCTION AT,SUBR
+
+       ENTRY
+       PUSHJ   P,ARGS1
+       SOJL    C,OUTRNG
+       PUSHJ   P,@ATTBL(E)
+       JRST    FINIS
+
+PRDISP ATTBL,IWTYP1,[[P2WORD,LAT],[PNWORD,UAT],[P2NWORD,VAT],[PARGS,AAT]
+[PCHSTR,STAT],[PTMPLT,TAT],[PBYTE,BTAT]]
+
+\f
+; NTH
+
+MFUNCTION NTH,SUBR
+
+       ENTRY
+
+       PUSHJ   P,ARGS1
+       SOJL    C,OUTRNG
+       PUSHJ   P,@NTHTBL(E)
+       JRST    FINIS
+
+PRDISP NTHTBL,IWTYP1,[[P2WORD,LNTH],[PNWORD,UNTH],[P2NWOR,VNTH],[PARGS,ANTH]
+[PCHSTR,SNTH],[PTMPLT,TMPLNT],[PBYTE,BNTH]]
+
+; GET
+
+MFUNCTION GET,SUBR
+
+       ENTRY
+       MOVE    E,IIGETP        ; MAKE ARG CHECKER FAIL INTO GETPROP
+       PUSHJ   P,ARGS5         ; CHECK ARGS
+       SOJL    C,OUTRNG
+       SKIPN   E,IGETBL(E)     ; GET DISPATCH ADR
+       JRST    IGETP           ; REALLY PUTPROP
+       JUMPE   0,TMA
+       PUSHJ   P,(E)           ; DISPATCH
+       JRST    FINIS
+
+PRDISP IGETBL,0,[[P2WORD,LNTH],[PNWORD,UNTH],[P2NWORD,VNTH],[PARGS,ANTH]
+[PCHSTR,SNTH],[PTMPLT,TMPLNT],[PBYTE,BNTH]]
+
+; GETL
+
+MFUNCTION GETL,SUBR
+
+       ENTRY
+       MOVE    E,IIGETL        ; ERROR HACK
+       PUSHJ   P,ARGS5
+       SOJL    C,OUTRNG        ; LOSER
+       SKIPN   E,IGTLTB(E)
+       JRST    IGETLO          ; REALLY GETPL
+       JUMPE   0,TMA
+       PUSHJ   P,(E)           ; DISPATCH
+       JRST    FINIS
+
+IIGETL:        JRST    IGETLO
+
+PRDISP IGTLTB,0,[[P2WORD,LAT],[PNWORD,UAT],[P2NWORD,VAT],[PARGS,AAT]
+[PCHSTR,STAT],[PBYTE,BTAT]]
+
+
+; ARG CHECKER FOR PUT/GET/GETL
+
+ARGS5: HLRE    0,AB            ; -# OF ARGS
+       ASH     0,-1
+       ADDI    0,2             ; 0 OR -1 WIN
+       JUMPG   0,TFA
+       AOJL    0,TMA           ; MORE THAN 3
+       JRST    ARGS3           ; GET ARGS
+\f
+; PUT
+
+MFUNCTION PUT,SUBR
+
+       ENTRY
+       MOVE    E,IIPUTP
+       PUSHJ   P,ARGS5         ; GET ARGS
+       SKIPN   E,IPUTBL(E)
+       JRST    IPUTP
+       CAML    AB,[-5,,]       ; SKIP IF GOOD ARRGS
+       JRST    TFA
+       SOJL    C,OUTRNG
+       PUSH    TP,4(AB)
+       PUSH    TP,5(AB)
+       PUSHJ   P,(E)
+       MOVE    A,(AB)          ; RET STRUCTURE
+       MOVE    B,1(AB)
+       JRST    FINIS
+
+PRDISP IPUTBL,0,[[P2WORD,LPUT],[PNWORD,UPUT],[P2NWORD,VPUT],[PARGS,APUT]
+[PCHSTR,SPUT],[PTMPLT,TMPPUT],[PBYTE,BPUT]]
+
+; IN
+
+MFUNCTION IN,SUBR
+
+       ENTRY   1
+
+       MOVEI   B,(AB)          ; POINT TO ARG
+       PUSHJ   P,PTYPE
+       MOVS    E,A             ; REAL DISPATCH TO E
+       MOVE    B,1(AB)
+       MOVE    A,(AB)
+       GETYP   C,A             ; IN CASE NEEDED
+       PUSHJ   P,@INTBL(E)
+       JRST    FINIS
+
+PRDISP INTBL,OTHIN,[[P2WORD,LNTH1],[PNWORD,UIN],[P2NWORD,VIN],[PARGS,AIN]
+[PCHSTR,SIN],[PTMPLT,TIN],[PBYTE,BINN]]
+
+OTHIN: CAIE    C,TLOCN         ; ASSOCIATION LOCATIVE
+       JRST    OTHIN1          ; MAYBE LOCD
+       HLLZ    0,VAL(B)
+       PUSHJ   P,RMONCH
+       MOVE    A,VAL(B)
+       MOVE    B,VAL+1(B)
+       POPJ    P,
+
+OTHIN1:        CAIN    C,TLOCD
+       JRST    VIN
+       JRST    WTYP1
+
+\f
+; SETLOC
+
+MFUNCTION SETLOC,SUBR
+
+       ENTRY   2
+
+       MOVEI   B,(AB)          ; POINT TO ARG
+       PUSHJ   P,PTYPE         ; DO TYPE
+       MOVS    E,A             ; REAL TYPE
+       MOVE    B,1(AB)
+       MOVE    C,2(AB)         ; PASS ARG
+       MOVE    D,3(AB)
+       MOVE    A,(AB)          ; IN CASE
+       GETYP   0,A
+       PUSHJ   P,@SETTBL(E)
+       MOVE    A,2(AB)
+       MOVE    B,3(AB)
+       JRST    FINIS
+
+PRDISP SETTBL,OTHSET,[[P2WORD,LSTUF],[PNWORD,USTUF],[P2NWORD,VSTUF],[PARGS,ASTUF]
+[PCHSTR,SSTUF],[PTMPLT,TSTUF],[PBYTE,BSTUF]]
+
+OTHSET:        CAIE    0,TLOCN         ; ASSOC?
+       JRST    OTHSE1
+       HLLZ    0,VAL(B)        ; GET MONITORS
+       PUSHJ   P,MONCH
+       MOVEM   C,VAL(B)
+       MOVEM   D,VAL+1(B)
+       POPJ    P,
+
+OTHSE1:        CAIE    0,TLOCD
+       JRST    WTYP1
+       JRST    VSTUF
+
+; LREST  -- REST A LIST IN B BY AMOUNT IN C
+
+LREST: MOVSI   A,TLIST
+       JUMPE   C,CPOPJ
+       MOVE    PVP,PVSTOR+1
+       MOVEM   A,BSTO(PVP)
+
+LREST2:        INTGO                   ;CHECK INTERRUPTS
+       JUMPE   B,OUTRNG        ; CANT CDR NIL
+       HRRZ    B,(B)           ;CDR THE LIST
+       SOJG    C,LREST2        ;COUNT DOWN
+       MOVE    PVP,PVSTOR+1
+       SETZM   BSTO(PVP)       ;RESET BSTO
+       POPJ    P,
+
+\f
+; VREST -- REST A VECTOR, AREST -- REST AN ARG BLOCK
+
+VREST: SKIPA   A,$TVEC         ; FINAL TYPE
+AREST: HRLI    A,TARGS
+       ASH     C,1             ; TIMES 2
+       JRST    UREST1
+
+; UREST  -- REST A UVECTOR
+
+STORST:        SKIPA   A,$TSTORA
+UREST: MOVSI   A,TUVEC
+UREST1:        JUMPE   C,CPOPJ
+       HRLI    C,(C)
+       JUMPL   C,OUTRNG
+       ADD     B,C             ; REST IT
+       CAILE   B,-1            ; OUT OF RANGE ?
+       JRST    OUTRNG
+       POPJ    P,
+
+
+; SREST -- REST A STRING
+
+BREST: SKIPA   D,[TBYTE]
+
+SREST: MOVEI   D,TCHSTR
+       PUSH    P,D
+       JUMPE   C,SREST1
+       PUSH    P,A             ; SAVE TYPE WORD
+       PUSH    P,C             ; SAVE AMOUNT
+       MOVEI   D,(A)           ; GET LENGTH
+       CAILE   C,(D)           ; SKIP IF OK
+       JRST    OUTRNG
+       LDB     D,[366000,,B]   ;POSITION FIELD OF BYTE POINTER
+       LDB     A,[300600,,B]   ;SIZE FIELD
+       PUSH    P,A             ;SAVE SIZE
+       IDIVI   D,(A)           ;COMPUT BYTES IN 1ST WORD
+       MOVEI   0,36.           ;NOW COMPUTE BYTES PER WORD
+       IDIVI   0,(A)           ;BYTES PER WORD IN 0
+       MOVE    E,0             ;COPY OF BYTES PER WORD TO E
+       SUBI    0,(D)           ;0 # OF UNSUED BYTES IN 1ST WORD
+       ADDB    C,0             ;C AND 0 NO.OF CHARS FROM WORD BOUNDARY
+       IDIVI   C,(E)           ;C/ REL WORD D/ CHAR IN LAST
+       ADDI    C,(B)           ;POINTO WORD WITH C
+       POP     P,A             ;RESTORE BITS PER BYTE
+       JUMPN   D,.+3           ; JUMP IF NOT WD BOUNDARY
+       MOVEI   D,(E)           ; USE FULL AMOUNT
+       SUBI    C,1             ; POINT TO PREV WORD
+       IMULI   A,(D)           ;A/ BITS USED IN LAST WORD
+       MOVEI   0,36.
+       SUBI    0,(A)           ;0 HAS NEW POSITION FIELD
+       DPB     0,[360600,,B]   ;INTO BYTE POINTER
+       HRRI    B,(C)           ;POINT TO RIGHT WORD
+       POP     P,C             ; RESTORE AMOUNT
+       POP     P,A
+       SUBI    A,(C)           ; NEW LENGTH
+SREST1:        POP     P,0
+       HRL     A,0
+       POPJ    P,
+
+; TMPRST -- REST A TEMPLATE DATA STRUCTURE
+
+TMPRST:        PUSHJ   P,TM.TOE        ; CHECK ALL BOUNDS ETC.
+       MOVSI   D,(D)
+       HLL     C,D
+       MOVE    B,C             ; RET IN B
+       MOVSI   A,TTMPLT
+       POPJ    P,
+
+; LAT  --  GET A LOCATIVE TO A LIST
+
+LAT:   PUSHJ   P,LREST         ; GET POINTER
+       JUMPE   B,OUTRNG        ; YOU LOSE!
+       MOVSI   A,TLOCL         ; NEW TYPE
+       POPJ    P,
+
+\f
+; UAT  --  GET A LOCATIVE TO A UVECTOR
+
+UAT:   PUSHJ   P,UREST 
+       MOVSI   A,TLOCU
+       JRST    POPJL
+
+; VAT  --  GET A LOCATIVE TO A VECTOR
+
+VAT:   PUSHJ   P,VREST         ; REST IT AND TYPE IT
+       MOVSI   A,TLOCV
+       JRST    POPJL
+
+; AAT  --  GET A LOCATIVE TO AN ARGS BLOCK
+
+AAT:   PUSHJ   P,AREST
+       HRLI    A,TLOCA
+POPJL: JUMPGE  B,OUTRNG        ; LOST
+       POPJ    P,
+
+; STAT  --  LOCATIVE TO A STRING
+
+STAT:  PUSHJ   P,SREST
+       TRNN    A,-1            ; SKIP IF ANY LEFT
+       JRST    OUTRNG
+       HRLI    A,TLOCS         ; LOCATIVE
+       POPJ    P,
+
+; BTAT  --  LOCATIVE TO A BYTE-STRING
+
+BTAT:  PUSHJ   P,BREST
+       TRNN    A,-1            ; SKIP IF ANY LEFT
+       JRST    OUTRNG
+       HRLI    A,TLOCB         ; LOCATIVE
+       POPJ    P,
+
+; TAT -- LOCATIVE TO A TEMPLATE
+
+TAT:   PUSHJ   P,TMPRST
+       PUSH    TP,A
+       PUSH    TP,B
+       GETYP   A,(B)           ; GET REAL SAT
+       SUBI    A,NUMSAT+1
+       HRLS    A               ; READY TO HIT TABLE
+       ADD     A,TD.LNT+1
+       JUMPGE  A,BADTPL
+       MOVE    C,B             ; DATUM TO C
+       XCT     (A)             ; GET LENGTH
+       HLRZS   C               ; REST COUNTER
+       SUBI    B,(C)           ; FLUSH IT OFF
+       JUMPE   B,OUTRNG
+       MOVE    B,(TP)
+       SUB     TP,[2,,2]
+       MOVSI   A,TLOCT
+       POPJ    P,
+       
+
+; LNTH  --  NTH OF LIST
+
+LNTH:  PUSHJ   P,LAT
+LNTH1: PUSHJ   P,RMONC0        ; CHECK READ MONITORS
+       HLLZ    A,(B)           ; GET GOODIE
+       MOVE    B,1(B)
+       JSP     E,CHKAB         ; HACK DEFER
+       POPJ    P,
+
+; VNTH  --  NTH A VECTOR, ANTH  --  NTH AN ARGS BLOCK
+
+ANTH:  PUSHJ   P,AAT
+       JRST    .+2
+
+VNTH:  PUSHJ   P,VAT
+AIN:
+VIN:   PUSHJ   P,RMONC0
+       MOVE    A,(B)
+       MOVE    B,1(B)
+       POPJ    P,
+
+; UNTH  --  NTH OF UVECTOR
+
+UNTH:  PUSHJ   P,UAT
+UIN:   HLRE    C,B             ; FIND DW
+       SUBM    B,C
+       HLLZ    0,(C)           ; GET MONITORS
+       MOVE    D,0
+       TLZ     D,TYPMSK#<-1>
+       PUSH    P,D
+       PUSHJ   P,RMONCH        ; CHECK EM
+       POP     P,A
+       MOVE    B,(B)           ; AND VALUE
+       POPJ    P,
+
+\f
+; BNTH -- NTH A BYTE STRING
+
+BNTH:  PUSHJ   P,BTAT
+BINN:  PUSH    P,$TFIX
+       JRST    SIN1
+
+; SNTH  --  NTH A STRING
+
+SNTH:  PUSHJ   P,STAT
+SIN:   PUSH    P,$TCHRS
+SIN1:  PUSH    TP,A
+       PUSH    TP,B            ; SAVE POINT BYTER
+       MOVEI   C,-1(TP)        ; FIND DOPE WORD
+       PUSHJ   P,BYTDOP
+       HLLZ    0,-1(A)         ; GET 
+       POP     TP,B
+       POP     TP,A
+       PUSHJ   P,RMONCH
+       ILDB    B,B             ; GET CHAR
+       POP     P,A
+       POPJ    P,
+
+; TIN -- IN OF A TEMPLATE
+
+TIN:   MOVEI   C,0
+
+; TMPLNT -- NTH A TEMPLATE DATA STRUCTURE
+
+TMPLNT:        ADDI    C,1
+       PUSHJ   P,TM.TOE        ; GET POINTER TO INS IN E
+       ADD     A,TD.GET+1      ; POINT TO GETTER
+       MOVE    A,(A)           ; GET VECTOR OF INS
+       ADDI    E,-1(A)         ; POINT TO INS
+       SUBI    D,1
+       XCT     (E)             ; DO IT
+       JFCL                    ; SKIP IF AN ANY CASE
+       POPJ    P,              ; RETURN
+
+; LPUT  --  PUT ON A LIST
+
+LPUT:  PUSHJ   P,LAT           ; POSITION
+       POP     TP,D
+       POP     TP,C
+
+; LSTUF -- HERE TO STUFF A LIST ELEMENT
+
+LSTUF: PUSHJ   P,MONCH0        ; CHECK OUT MONITOR BITS
+       GETYP   A,C             ; ISOLATE TYPE
+       PUSHJ   P,NWORDT        ; NEED TO DEFER?
+       SOJN    A,DEFSTU
+       HLLM    C,(B)   
+       MOVEM   D,1(B)          ; AND VAL
+       POPJ    P,
+
+DEFSTU:        PUSH    TP,$TLIST
+       PUSH    TP,B
+       PUSH    TP,C
+       PUSH    TP,D
+       PUSHJ   P,CELL2         ; GET WORDS
+       POP     TP,1(B)
+       POP     TP,(B)
+       MOVE    E,(TP)
+       SUB     TP,[2,,2]
+       MOVEM   B,1(E)
+       HLLZ    0,(E)           ; GET OLD MONITORS
+       TLZ     0,TYPMSK        ; KILL TYPES
+       TLO     0,TDEFER        ; MAKE DEFERRED
+       HLLM    0,(E)
+       POPJ    P,
+
+; VPUT -- PUT ON A VECTOR , APUT -- PUT ON AN RG BLOCK
+
+APUT:  PUSHJ   P,AAT
+       JRST    .+2
+
+VPUT:  PUSHJ   P,VAT           ; TREAT LIKE VECTOR
+       POP     TP,D            ; GET GOODIE BACK
+       POP     TP,C
+
+; AVSTUF --  CLOBBER ARGS AND VECTORS
+
+ASTUF:
+VSTUF: PUSHJ   P,MONCH0
+       MOVEM   C,(B)
+       MOVEM   D,1(B)
+       POPJ    P,
+
+\f
+
+
+; UPUT  --  CLOBBER A UVECTOR
+
+UPUT:  PUSHJ   P,UAT           ; GET IT RESTED
+       POP     TP,D
+       POP     TP,C
+
+; USTUF -- HERE TO CLOBBER A UVECTOR
+
+USTUF: HLRE    E,B
+       SUBM    B,E             ; C POINTS TO DOPE
+       GETYP   A,(E)           ; GET UTYPE
+       GETYP   0,C
+       CAIE    0,(A)           ; CHECK SAMENESS
+       JRST    WRNGUT
+       HLLZ    0,(E)           ; MONITOR BITS IN DOPE WORD
+       MOVSI   A,TLOCU         ; CHOMP, CHOMP (WAS TUVEC) -- MARC 5/2/78
+       PUSHJ   P,MONCH
+       MOVEM   D,(B)           ; SMASH
+       POPJ    P,
+
+; BPUT -- HERE TO PUT A BYTE-STRING
+
+BPUT:  PUSHJ   P,BTAT
+       POP     TP,D
+       POP     TP,C
+BSTUF: MOVEI   E,TFIX
+       JRST    SSTUF1
+
+; SPUT -- HERE TO PUT A STRING
+
+SPUT:  PUSHJ   P,STAT          ; REST IT
+       POP     TP,D
+       POP     TP,C
+
+; SSTUF -- STUFF A STRING
+
+SSTUF: MOVEI   E,TCHRS
+SSTUF1:        GETYP   0,C             ; BETTER BE CHAR
+       CAIE    0,(E)
+       JRST    WTYP3
+       PUSH    P,C
+       PUSH    TP,A
+       PUSH    TP,B
+       MOVEI   C,-1(TP)        ; FIND D.W.
+       PUSHJ   P,BYTDOP
+       SKIPGE  (A)-1           ; SKIP IF NOT REALLY ATOM
+       JRST    PNMNG
+       HLLZ    0,(A)-1         ; GET MONITORS
+       POP     TP,B
+       POP     TP,A
+       POP     P,C
+       PUSHJ   P,MONCH
+       IDPB    D,B             ; STASH
+       POPJ    P,
+
+PNMNG: POP     TP,B
+       POP     TP,A
+       PUSH    TP,$TATOM
+       PUSH    TP,EQUOTE ATTEMPT-TO-MUNG-ATOMS-PNAME
+       HRLI    A,TCHSTR
+       PUSH    TP,A
+       PUSH    TP,B
+       MOVEI   A,2
+       JRST    CALER
+
+; TSTUF -- SETLOC A TEMPLATE
+
+TSTUF: PUSH    TP,C
+       PUSH    TP,D
+       MOVEI   C,0
+
+; PUTTMP -- TEMPLATE PUTTER
+
+TMPPUT:        ADDI    C,1
+       PUSHJ   P,TM.TOE        ; GET E POINTING TO SLOT #
+       ADD     A,TD.PUT+1      ; POINT TO INS
+       MOVE    A,(A)           ; GET VECTOR OF INS
+       ADDI    E,-1(A)
+       POP     TP,B            ; NEW VAL TO A AND B
+       POP     TP,A
+       SUBI    D,1
+       XCT     (E)             ; DO IT
+       JRST    BADPUT
+       POPJ    P,
+
+TM.LN1:        SUBI    0,NUMSAT+1
+       HRRZ    A,0             ; RET FIXED OFFSET
+       HRLS    0
+       ADD     0,TD.LNT+1      ; USE LENGTHERS FOR TEST
+       JUMPGE  0,BADTPL
+       PUSH    P,C
+       MOVE    C,B
+       HRRZS   0               ; POINT TO TABLE ENTRY
+       PUSH    P,A
+       XCT     @0              ; DO IT
+       POP     P,A
+       POP     P,C
+       POPJ    P,
+
+TM.TBL:        MOVEI   E,(D)           ; TENTATIVE WINNER IN E
+       TLNN    B,-1            ; SKIP IF REST HAIR EXISTS
+       POPJ    P,              ; NO, WIN
+
+       PUSH    P,A             ; SAVE OFFSET
+       HRLS    A               ; A IS REL OFFSET TO INS TABLE
+       ADD     A,TD.GET+1      ; GET ONEOF THE TABLES
+       MOVE    A,(A)           ; TABLE POINTER TO A
+       MOVSI   0,-1(D)         ; START SEEING IF PAST TEMP SPEC
+       ADD     0,A
+       JUMPL   0,CPOPJA        ; JUMP IF E STILL VALID
+       HLRZ    E,B             ; BASIC LENGTH TO E
+       HLRE    0,A             ; LENGTH OF TEMPLATE TO 0
+       ADDI    0,(E)           ; 0 ==> # ELEMENTS IN REPEATING SEQUENCE
+       MOVNS   0
+       SUBM    D,E             ; E ==> # PAST BASIC WANTED
+       EXCH    0,E
+       IDIVI   0,(E)           ; A ==> REL REST GUY WANTED
+       HLRZ    E,B
+       ADDI    E,1(A)
+CPOPJA:        POP     P,A
+       POPJ    P,
+
+; TM.TOE -- GET RIGHT TEMPLATE # IN E
+; C/ OBJECT #, B/ OBJECT POINTER
+
+TM.TOE:        GETYP   0,(B)           ; GET REAL SAT
+       MOVEI   D,(C)           ; OBJ # TO D
+       HLRZ    C,B             ; REST COUNT
+       ADDI    D,(C)           ; FUDGE FOR REST COUNTER
+       MOVE    C,B             ; POINTER TO C
+       PUSHJ   P,TM.LN1        ; GET LENGTH IN B (WATCH LH!)
+       CAILE   D,(B)           ; CHECK RANGE
+       JRST    OUTRNG          ; LOSER, QUIT
+       JRST    TM.TBL          ; GO COMPUTE TABLE OFFSET
+               
+\f; ROUTINE FOR COMPILER CALLS RETS CODE IN E GOODIE IN A AND B
+; FIXES (P)
+
+CPTYEE:        MOVE    E,A
+       GETYP   A,A
+       PUSHJ   P,CPTYPE
+       JUMPE   A,WTYPUN
+       SUBM    M,-1(P)
+       EXCH    E,A
+       POPJ    P,
+
+; COMPILER CALLS TO MANY OF THESE GUYS
+
+CIREST:        PUSHJ   P,CPTYEE        ; TYPE OF DISP TO E
+       HRRES   C               ; CLEAR LH, IN CASE IT'S AN OFFSET
+       JUMPL   C,OUTRNG
+       CAIN    0,SSTORE
+       JRST    CIRST1
+       PUSHJ   P,@RESTBL(E)
+       JRST    MPOPJ
+
+CIRST1:        PUSHJ   P,STORST
+       JRST    MPOPJ
+
+CINTH: PUSHJ   P,CPTYEE
+       HRRES   C               ; CLEAR LH
+       SOJL    C,OUTRNG        ; CHECK BOUNDS
+       PUSHJ   P,@NTHTBL(E)
+       JRST    MPOPJ
+
+CIAT:  PUSHJ   P,CPTYEE
+       SOJL    C,OUTRNG
+       PUSHJ   P,@ATTBL(E)
+       JRST    MPOPJ
+
+CSETLO:        PUSHJ   P,CTYLOC
+       MOVSS   E               ; REAL DISPATCH
+       GETYP   0,A             ; INCASE LOCAS OR LOCD
+       PUSH    TP,C
+       PUSH    TP,D
+       PUSHJ   P,@SETTBL(E)
+       POP     TP,B
+       POP     TP,A
+       JRST    MPOPJ
+
+CIN:   PUSHJ   P,CTYLOC
+       MOVSS   E               ; REAL DISPATCH
+       GETYP   C,A
+       PUSHJ   P,@INTBL(E)
+       JRST    MPOPJ
+
+CTYLOC:        MOVE    E,A
+       GETYP   A,A
+       PUSHJ   P,CPTYPE
+       SUBM    M,-1(P)
+       EXCH    A,E
+       POPJ    P,
+
+; COMPILER'S PUT,GET AND GETL
+
+CIGET: PUSH    P,[0]
+       JRST    .+2
+
+CIGETL:        PUSH    P,[1]
+       MOVE    E,A
+       GETYP   A,A
+       PUSHJ   P,CPTYPE
+       EXCH    A,E
+       JUMPE   E,CIGET1        ; REAL GET, NOT NTH
+       GETYP   0,C             ; INDIC FIX?
+       CAIE    0,TFIX
+        CAIN   0,TOFFS
+         JRST  .+2
+       JRST    CIGET1
+       POP     P,E             ; GET FLAG
+       AOS     (P)             ; ALWAYS SKIP
+       MOVE    C,D             ; # TO AN AC
+       JRST    @.+1(E)
+               SETZ CINTH
+               SETZ CIAT
+
+CIGET1:        POP     P,E             ; GET FLAG
+       JRST    @GETTR(E)       ; DO A REAL GET
+
+GETTR:         SETZ CIGTPR
+               SETZ CIGETP
+
+CIPUT: SUBM    M,(P)
+       MOVE    E,A
+       GETYP   A,A
+       PUSHJ   P,CPTYPE
+       EXCH    A,E
+       PUSH    TP,-1(TP)               ; PAIN AND SUFFERING
+       PUSH    TP,-1(TP)
+       MOVEM   A,-3(TP)
+       MOVEM   B,-2(TP)
+       JUMPE   E,CIPUT1
+       GETYP   0,C
+       CAIE    0,TFIX          ; YES DO STRUCT
+        CAIN   0,TOFFS
+         JRST  .+2
+       JRST    CIPUT1
+       MOVE    C,D
+       HRRES   C
+       SOJL    C,OUTRNG        ; CHECK BOUNDS
+       PUSHJ   P,@IPUTBL(E)
+PMPOPJ:        POP     TP,B
+       POP     TP,A
+       JRST    MPOPJ
+
+CIPUT1:        PUSHJ   P,IPUT
+       JRST    PMPOPJ
+\f
+; SMON -- SET MONITOR BITS
+;      B/ <POINTER TO LOCATIVE>
+;      D/ <IORM> OR <ANDCAM>
+;      E/ BITS
+
+SMON:  GETYP   A,(B)
+       PUSHJ   P,PTYPE         ; TO PRIM TYPE
+       HLRZS   A
+       SKIPE   A,SMONTB(A)     ; DISPATCH?
+       JRST    (A)
+
+; COULD STILL BE LOCN OR LOCD
+
+       GETYP   A,(B)           ; TYPE BACK
+       CAIE    A,TLOCN
+       JRST    SMON2           ; COULD BE LOCD
+       MOVE    C,1(B)          ; POINT
+       HRRI    D,VAL(C)        ; MAKE INST POINT
+       JRST    SMON3
+
+SMON2: CAIE    A,TLOCD
+       JRST    WRONGT
+
+
+; SET LIST/TUPLE/ID LOCATIVE
+
+SMON4: HRR     D,1(B)          ; POINT TO TYPE WORD
+SMON3: XCT     D
+       POPJ    P,
+
+; SET UVEC LOC
+
+SMON5: HRRZ    C,1(B)          ; POINT TO TOP OF UV
+       HLRE    0,1(B)
+       SUB     C,0             ; POINT TO DOPE
+       HRRI    D,(C)           ; POINT IN INST
+       JRST    SMON3
+
+; SET CHSTR LOC
+
+SMON6: MOVEI   C,(B)           ; FOR BYTDOP
+       PUSHJ   P,BYTDOP        ; POINT TO DOPE
+       HRRI    D,(A)-1
+       JRST    SMON3
+
+PRDISP SMONTB,0,[[P2WORD,SMON4],[P2NWOR,SMON4],[PARGS,SMON4]
+[PNWORD,SMON5],[PCHSTR,SMON6],[PBYTE,SMON6]]
+
+\f
+; COMPILER'S MONAD?
+
+CIMON: PUSH    P,A
+       GETYP   A,A
+       PUSHJ   P,CPTYPE
+       JUMPE   A,CIMON1
+       POP     P,A
+       JRST    CEMPTY
+
+CIMON1:        POP     P,A
+       JRST    YES
+
+; FUNCTION TO DECIDE IF FURTHER DECOMPOSITION POSSIBLE
+
+MFUNCTION MONAD,SUBR,MONAD?
+
+       ENTRY   1
+
+       MOVE    B,AB            ; CHECK PRIM TYPE
+       PUSHJ   P,PTYPE
+       JUMPE   A,ITRUTH                ;RETURN ARGUMENT
+       SKIPE   B,1(AB)
+       JRST    @MONTBL(A)      ;DISPATCH ON PTYPE
+       JRST    ITRUTH
+
+PRDISP MONTBL,IFALSE,[[P2NWORD,MON1],[PNWORD,MON1],[PARGS,MON1]
+[PCHSTR,CHMON],[PTMPLT,TMPMON],[PBYTE,CHMON]]
+
+MON1:  JUMPGE  B,ITRUTH                ;EMPTY VECTOR
+       JRST    IFALSE
+
+CHMON: HRRZ    B,(AB)
+       JUMPE   B,ITRUTH
+       JRST    IFALSE
+
+TMPMON:        PUSHJ   P,LNTMPL
+       JUMPE   B,ITRUTH
+       JRST    IFALSE
+
+CISTRU:        GETYP   A,A             ; COMPILER CALL
+       PUSHJ   P,ISTRUC
+       JRST    NO
+       JRST    YES
+
+ISTRUC:        PUSHJ   P,SAT           ; STORAGE TYPE
+       SKIPE   A,PRMTYP(A)
+       AOS     (P)             ; SKIP IF WINS
+       POPJ    P,
+
+; SUBR TO CHECK FOR LOCATIVE
+
+MFUNCTION %LOCA,SUBR,[LOCATIVE?]
+
+       ENTRY   1
+       GETYP   A,(AB)  
+       PUSHJ   P,LOCQQ
+       JRST    IFALSE
+       JRST    ITRUTH
+
+; SKIPS IF TYPE IN A IS A LOCATIVE
+
+LOCQ:  GETYP   A,(B)           ; GET TYPE
+LOCQQ: PUSH    P,A             ; SAVE FOR LOCN/LOCD
+       PUSHJ   P,SAT
+       MOVE    A,PRMTYP(A)
+       JUMPE   A,LOCQ1
+       SUB     P,[1,,1]
+       TRNN    A,-1
+LOCQ2: AOS     (P)
+       POPJ    P,
+
+LOCQ1: POP     P,A             ; RESTORE TYPE
+       CAIE    A,TLOCN
+       CAIN    A,TLOCD
+       JRST    LOCQ2
+       POPJ    P,
+
+\f
+; FUNCTION TO DETERMINE MEMBERSHIP IN LISTS AND VECTORS
+
+MFUNCTION MEMBER,SUBR
+
+       MOVE    E,[PUSHJ P,EQLTST]      ;TEST ROUTINE IN E
+       JRST    MEMB
+
+MFUNCTION MEMQ,SUBR
+
+       MOVE    E,[PUSHJ P,EQTST]       ;EQ TESTER
+
+MEMB:  ENTRY   2
+       MOVE    B,AB            ;POINT TO FIRST ARG
+       PUSHJ   P,PTYPE         ;CHECK PRIM TYPE
+       ADD     B,[2,,2]        ;POINT TO 2ND ARG
+       PUSHJ   P,PTYPE
+       JUMPE   A,WTYP2         ;2ND WRONG TYPE
+       PUSH    TP,(AB)
+       PUSH    TP,1(AB)
+       MOVE    C,2(AB)         ; FOR TUPLE CASE
+       SKIPE   B,3(AB)         ;GOBBLE LIST VECTOR ETC. POINTER
+       PUSHJ   P,@MEMTBL(A)    ;DISPATCH
+       JRST    IFALSE          ;OR REPORT LOSSAGE
+       JRST    FINIS
+
+PRDISP MEMTBL,IWTYP2,[[P2WORD,MEMLST],[PNWORD,MUVEC],[P2NWORD,MEMVEC]
+[PARGS,MEMTUP],[PCHSTR,MEMCH],[PTMPLT,MEMTMP],[PBYTE,MEMBYT]]
+
+
+
+MEMLST:        MOVSI   0,TLIST         ;SET B'S TYPE TO LIST
+       MOVE    PVP,PVSTOR+1
+       MOVEM   0,BSTO(PVP)
+       JUMPE   B,MEMLS6        ; EMPTY LIST LOSE IMMEDIATE
+
+MEMLS1:        INTGO                   ;CHECK INTERRUPTS
+       MOVEI   C,(B)           ;COPY POINTER
+       GETYP   D,(C)           ;GET TYPE
+       MOVSI   A,(D)           ;COPY
+       CAIE    D,TDEFER                ;DEFERRED?
+       JRST    MEMLS2
+       MOVE    C,1(C)          ;GET DEFERRED DATUM
+       GETYPF  A,(C)           ;GET FULL TYPE WORD
+MEMLS2:        MOVE    C,1(C)          ;GET DATUM
+       XCT     E               ;DO THE COMPARISON
+       JRST    MEMLS3          ;NO MATCH
+       MOVSI   A,TLIST
+MEMLS5:        AOS     (P)
+MEMLS6:        MOVE    PVP,PVSTOR+1
+       SETZM   BSTO(PVP)               ;RESET B'S TYPE
+       POPJ    P,
+
+MEMLS3:        HRRZ    B,(B)           ;STEP THROGH
+       JUMPN   B,MEMLS1        ;STILL MORE TO DO
+MEMLS4:        MOVSI   A,TFALSE        ;RETURN FALSE
+       JRST    MEMLS6          ;RETURN 0
+
+MEMTUP:        HRRZ    A,C
+       TLOA    A,TARGS
+MEMVEC:        MOVSI   A,TVEC          ;CLOBBER B'S TYPE TO VECTOR
+       JUMPGE  B,MEMLS4        ;EMPTY VECTOR
+       MOVE    PVP,PVSTOR+1
+       MOVEM   A,BSTO(PVP)
+
+MEMV1: INTGO                   ;CHECK FOR INTS
+       GETYPF  A,(B)           ;GET FULL TYPE
+       MOVE    C,1(B)          ;AND DATA
+       XCT     E               ;DO COMPARISON INS
+       JRST    MEMV2           ;NOT EQUAL
+       MOVE    PVP,PVSTOR+1
+       MOVE    A,BSTO(PVP)
+       JRST    MEMLS5          ;RETURN WITH POINTER
+\f
+MEMV2: ADD     B,[2,,2]        ;INCREMENT AND GO
+       JUMPL   B,MEMV1         ;STILL WINNING
+MEMV3: MOVEI   B,0
+       JRST    MEMLS4          ;AND RETURN FALSE
+
+MUVEC: JUMPGE  B,MEMLS4
+       GETYP   A,-1(TP)        ;GET TYPE OF GODIE
+       HLRE    C,B             ;LOOK FOR UNIFORM TYPE
+       SUBM    B,C             ;DOPE POINTER TO C
+       GETYP   C,(C)           ;GET THE TYPE
+       CAIE    A,(C)           ;ARE THEY THE SAME?
+       JRST    MEMLS4          ;NO, LOSE
+       MOVSI   A,TUVEC
+       CAIN    0,SSTORE
+       MOVSI   A,TSTORA
+       PUSH    P,A
+       MOVE    PVP,PVSTOR+1
+       MOVEM   A,BSTO(PVP)
+       MOVSI   A,(C)           ;TYPE TO LH
+       PUSH    P,A             ; SAVE FOR EACH TEST
+
+MUVEC1:        INTGO                   ;CHECK OUT INTS
+       MOVE    C,(B)           ;GET DATUM
+       MOVE    A,(P)           ; GET TYPE
+       XCT     E               ;COMPARE
+       AOBJN   B,MUVEC1        ;LOOP TO WINNAGE
+       SUB     P,[1,,1]
+       POP     P,A
+       JUMPGE  B,MEMV3         ;LOSE RETURN
+
+MUVEC2:        JRST    MEMLS5
+
+
+MEMBYT:        MOVEI   0,TFIX
+       MOVEI   D,TBYTE
+       JRST    MEMBY1
+
+MEMCH: MOVEI   0,TCHRS
+       MOVEI   D,TCHSTR
+MEMBY1:        GETYP   A,-1(TP)        ;IS ARG A SINGLE CHAR
+       CAIE    0,(A)           ;SKIP IF POSSIBLE WINNER
+       JRST    MEMSTR
+       MOVEI   0,(C)
+       MOVE    D,(TP)          ; AND CHAR
+
+MEMCH1:        SOJL    0,MEMV3
+       MOVE    E,B
+       ILDB    A,B
+       CAIE    A,(D)           ;CHECK IT
+       SOJA    C,MEMCH1
+
+MEMCH2:        MOVE    B,E
+       MOVE    A,C
+       JRST    MEMLS5
+
+MEMSTR:        CAIN    A,(D)
+       CAME    E,[PUSHJ P,EQLTST]
+       JRST    MEMV3
+       LDB     A,[300600,,(TP)]
+       LDB     0,[300600,,B]
+       CAIE    0,(A)
+       JRST    MEMV3
+       MOVEI   0,(C)           ; GET # OF CHAR INTO 0
+       ILDB    D,(TP)
+       PUSH    P,D             ; PUTS 1ST CHAR OF 1ST ARG ONTO STACK
+
+MEMST1:        SOJL    0,MEMLS ; HUNTS FOR FIRST MATCHING CHAR
+       MOVE    E,B
+       ILDB    A,B
+       CAME    A,(P)
+       SOJA    C,MEMST1        ; MATCH FAILS TRY NEXT
+
+       PUSH    P,B
+       PUSH    P,E
+       PUSH    P,C
+       PUSH    P,0
+       MOVE    E,(TP)          ; MATCH WINS SAVE OLD VALUES FOR FAILING LOOP
+       HRRZ    C,-1(TP)        ; LENGTH OF 1ARG
+MEMST2:        SOJE    C,MEMWN         ; WON -RAN OUT OF 1ARG FIRST-
+       SOJL    MEMLSR          ; LOST -RAN OUT OF 2ARG-
+       ILDB    A,B
+       ILDB    D,E
+       CAIN    A,(D)           ; SKP IF POSSIBLY LOST -BACK TO MEMST1-
+       JRST    MEMST2
+
+       POP     P,0
+       POP     P,C
+       POP     P,E
+       POP     P,B
+       SOJA    C,MEMST1
+
+MEMWN: MOVE    B,-2(P)         ; SETS UP ARGS LIKE MEMCH2 - HAVE WON
+       MOVE    A,-1(P)
+       SUB     P,[5,,5]
+       JRST    MEMLS5
+
+MEMLSR:        SUB     P,[5,,5]
+       JRST    MEMV3
+
+MEMLS: SUB     P,[1,,1]
+       JRST    MEMV3
+
+; MEMBERSHIP FOR TEMPLATE HACKER
+
+MEMTMP:        GETYP   0,(B)           ; GET REAL SAT
+       PUSH    P,E
+       PUSH    P,0
+       PUSH    TP,A
+       PUSH    TP,B            ; SAVE GOOEIE
+       PUSHJ   P,TM.LN1        ; GET LENGTH
+       MOVEI   B,(B)
+       HLRZ    A,(TP)          ; FUDGE FOR REST
+       SUBI    B,(A)
+       PUSH    P,B             ; SAVE LENGTH
+       PUSH    P,[-1]
+       POP     TP,B
+       POP     TP,A
+       MOVE    PVP,PVSTOR+1
+       MOVEM   B,BSTO+1(PVP)
+
+MEMTM1:        MOVE    PVP,PVSTOR+1
+       SETZM   BSTO(PVP)
+       AOS     C,(P)
+       SOSGE   -1(P)
+       JRST    MEMTM2
+       MOVE    0,-2(P)
+       PUSHJ   P,TMPLNT        ; GET ITEM
+       EXCH    C,B             ; VALUE TO C, POINTER BACK TO B
+       MOVE    E,-3(P)
+       MOVSI   0,TTMPLT
+       MOVE    PVP,PVSTOR+1
+       MOVEM   0,BSTO(PVP)
+       XCT     E
+       SKIPA
+       JRST    MEMTM3
+       MOVE    PVP,PVSTOR+1
+       MOVE    B,BSTO+1(PVP)
+       JRST    MEMTM1
+
+MEMTM3:        MOVE    PVP,PVSTOR+1
+       MOVE    B,BSTO+1(PVP)
+       HRL     B,(P)           ; DO APPROPRIATE REST
+       AOS     -4(P)
+MEMTM2:        SUB     P,[4,,4]
+       MOVSI   A,TTMPLT
+       MOVE    PVP,PVSTOR+1
+       SETZM   BSTO(PVP)
+       POPJ    P,
+
+EQTST: GETYP   A,A
+       GETYP   0,-1(TP)
+       CAMN    C,(TP)          ;CHECK VALUE
+       CAIE    0,(A)           ;AND TYPE
+       POPJ    P,
+       JRST    CPOPJ1
+
+EQLTST:        MOVE    PVP,PVSTOR+1
+       PUSH    TP,BSTO(PVP)
+       PUSH    TP,B
+       PUSH    TP,A
+       PUSH    TP,C
+       SETZM   BSTO(PVP)
+       PUSH    P,E             ;SAVE INS
+       MOVEI   C,-5(TP)        ;SET UP CALL TO IEQUAL
+       MOVEI   D,-1(TP)
+       AOS     -1(P)           ;ASSUME SKIP
+       PUSHJ   P,IEQUAL        ;GO INO EQUAL
+       SOS     -1(P)           ;UNDO SKIP
+       SUB     TP,[2,,2]       ;AND POOP OF CRAP
+       POP     TP,B
+       MOVE    PVP,PVSTOR+1
+       POP     TP,BSTO(PVP)
+       POP     P,E
+       POPJ    P,
+
+; COMPILER MEMQ AND MEMBER
+
+CIMEMB:        SKIPA   E,[PUSHJ P,EQLTST]
+
+CIMEMQ:        MOVE    E,[PUSHJ P,EQTST]
+       SUBM    M,(P)
+       PUSH    TP,A
+       PUSH    TP,B
+       GETYP   A,C
+       PUSHJ   P,CPTYPE
+       JUMPE   A,WTYPUN
+       MOVE    B,D             ; STRUCT TO B
+       PUSHJ   P,@MEMTBL(A)
+       TDZA    0,0             ; FLAG NO SKIP
+       MOVEI   0,1             ; FLAG SKIP
+       SUB     TP,[2,,2]
+       JUMPE   0,NOM
+       SOS     (P)             ; SKIP RETURN
+       JRST    MPOPJ
+\f
+
+; FUNCTION TO RETURN THE TOP OF A VECTOR , CSTRING OR UNIFORM VECTOR
+
+MFUNCTION TOP,SUBR
+
+       ENTRY   1
+
+       MOVE    B,AB            ;CHECK ARG
+       PUSHJ   P,PTYPE
+       MOVEI   E,(A)
+       MOVE    A,(AB)
+       MOVE    B,1(AB)
+       PUSHJ   P,@TOPTBL(E)    ;DISPATCH
+       JRST    FINIS
+
+PRDISP TOPTBL,IWTYP1,[[PNWORD,UVTOP],[P2NWORD,VTOP],[PCHSTR,CHTOP],[PARGS,ATOP]
+[PTMPLT,BCKTOP],[PBYTE,BTOP]]
+
+BCKTOP:        MOVEI   B,(B)           ; FIX UP POINTER
+       MOVSI   A,TTMPLT
+       POPJ    P,
+
+UVTOP: SKIPA   A,$TUVEC
+VTOP:  MOVSI   A,TVEC
+       CAIN    0,SSTORE
+       MOVSI   A,TSTORA
+       JUMPE   B,CPOPJ
+       HLRE    C,B             ;AND -LENGTH
+       HRRZS   B
+       SUB     B,C             ;POINT TO DOPE WORD
+       HLRZ    D,1(B)          ;TOTAL LENGTH
+       SUBI    B,-2(D)         ;POINT TO TOP
+       MOVNI   D,-2(D)         ;-LENGTH
+       HRLI    B,(D)           ;B NOW POINTS TO TOP
+       POPJ    P,
+
+BTOP:  SKIPA   E,$TBYTE
+CHTOP: MOVSI   E,TCHSTR
+       JUMPE   B,CPOPJ
+       PUSH    P,E
+       PUSH    TP,A
+       PUSH    TP,B
+       LDB     0,[360600,,(TP)]        ; POSITION FIELD
+       LDB     E,[300600,,(TP)]        ; AND SIZE FILED
+       IDIVI   0,(E)           ; 0/ BYTES IN 1ST WORD
+       MOVEI   C,36.           ; BITS PER WORD
+       IDIVI   C,(E)           ; BYTES PER WORD
+       PUSH    P,C
+       SUBM    C,0             ; UNUSED BYTES I 1ST WORD
+       ADD     0,-1(TP)        ; LENGTH OF WORD BOUNDARIED STRING
+       MOVEI   C,-1(TP)        ; GET DOPE WORD
+       PUSHJ   P,BYTDOP
+       HLRZ    C,(A)           ; GET LENGTH
+       SKIPGE  -1(A)           ; SKIP IF NOT REALLY ATOM
+       SUBI    C,3             ; IF IT IS, 3 LESS WORDS
+       SUBI    A,-1(C)         ;  START +1
+       MOVEI   B,-1(A)         ; SETUP BYTER
+       SUB     A,(TP)          ; WORDS DIFFERENT
+       IMUL    A,(P)           ; CHARS EXTRA
+       SUBM    0,A             ; FINAL TOTAL TO A
+       HLL     A,-1(P)
+       MOVE    C,(P)
+       SUB     P,[2,,2]
+       DPB     E,[300600,,B]
+       IMULI   E,(C)           ; BITS USED IN FULL WORD
+       MOVEI   C,36.
+       SUBI    C,(E)           ; WHERE TO POINT IN EMPTY? CASE
+       DPB     C,[360600,,B]
+       SUB     TP,[2,,2]
+       POPJ    P,
+\f
+
+
+ATOP:
+
+GETATO:        HLRE    C,B             ;GET -LENGTH
+       HRROS   B
+       SUB     B,C             ;POINT PAST
+       GETYP   0,(B)           ;GET NEXT TYPE (ASSURED OF BEING EITHER TINFO OR TENTRY)
+       CAIN    0,TENTRY                ;IF ENTRY
+       JRST    EASYTP          ;WANT UNEVALUATED ARGS
+       HRRE    C,(B)           ;ELSE-- GET NO. OF ARGS (*-2)
+       SUBI    B,(C)           ;GO TO TOP
+       TLCA    B,-1(C)         ;STORE NUMBER IN TOP POINTER
+EASYTP:        MOVE    B,FRAMLN+ABSAV(B)       ;GET ARG POINTER
+       HRLI    A,TARGS
+       POPJ    P,
+
+; COMPILERS ENTRY TO TOP
+
+CITOP: PUSHJ   P,CPTYEE
+       CAIN    E,P2WORD        ; LIST?
+       JRST    WTYPL
+       PUSHJ   P,@TOPTBL(E)
+       JRST    MPOPJ
+
+; FUNCTION TO CLOBBER THE CDR OF A LIST
+
+MFUNCTION PUTREST,SUBR,[PUTREST]
+       ENTRY   2
+
+       MOVE    B,AB            ;COPY ARG POINTER
+       PUSHJ   P,PTYPE         ;CHECK IT
+       CAIE    A,P2WORD        ;LIST?
+       JRST    WTYP1           ;NO, LOSE
+       ADD     B,[2,,2]        ;AND NEXT ONE
+       PUSHJ   P,PTYPE
+       CAIE    A,P2WORD
+       JRST    WTYP2           ;NOT LIST, LOSE
+       HRRZ    B,1(AB)         ;GET FIRST
+       JUMPE   B,OUTRNG
+       MOVE    D,3(AB)         ;AND 2D LIST
+       CAIL    B,HIBOT
+       JRST    PURERR
+       HRRM    D,(B)           ;CLOBBER
+       MOVE    A,(AB)          ;RETURN CALLED TYPE
+       JRST    FINIS
+
+\f
+
+; FUNCTION TO BACK UP A VECTOR, UVECTOR OR CHAR STRING
+
+MFUNCTION BACK,SUBR
+
+       ENTRY
+
+       MOVEI   C,1             ;ASSUME BACKING UP ONE
+       JUMPGE  AB,TFA          ;NO ARGS IS TOO FEW
+       CAML    AB,[-2,,0]      ;SKIP IF MORE THAN 2 ARGS
+       JRST    BACK1           ;ONLY ONE ARG
+       GETYP   A,2(AB)         ;GET TYPE
+       CAIE    A,TFIX          ;MUST BE FIXED
+       JRST    WTYP2
+       SKIPGE  C,3(AB)         ;GET NUMBER
+       JRST    OUTRNG
+       CAMGE   AB,[-4,,0]      ;SKIP IF WINNING NUMBER OF ARGS
+       JRST    TMA
+BACK1: MOVE    B,AB            ;SET UP TO FIND TYPE
+       PUSHJ   P,PTYPE         ;GET PRIM TYPE
+       MOVEI   E,(A)
+       MOVE    A,(AB)
+       SKIPN   B,1(AB)         ;GET DATUM
+       JRST    OUTRNG
+       PUSHJ   P,@BCKTBL(E)
+       JRST    FINIS
+
+PRDISP BCKTBL,IWTYP2,[[PNWORD,BACKU],[P2NWORD,BACKV],[PCHSTR,BACKC],[PARGS,BACKA]
+[PTMPLT,BCKTMP],[PBYTE,BACKB]]
+
+BACKV: LSH     C,1             ;GENERAL, DOUBLE AMOUNT
+       SKIPA   A,$TVEC
+BACKU: MOVSI   A,TUVEC
+       CAIN    0,SSTORE
+       MOVSI   A,TSTORA
+       HRLI    C,(C)           ;TO BOTH HALVES
+       SUB     B,C             ;BACK UP VECTOR POINTER
+       HLRE    C,B             ;FIND OUT IF OVERFLOW
+       SUBM    B,C             ;DOPE POINTER TO C
+       HLRZ    D,1(C)          ;GET LENGTH
+       SUBI    C,-2(D)         ;POINT TO TOP
+       ANDI    C,-1
+       CAILE   C,(B)           ;SKIP IF A WINNER
+       JRST    OUTRNG          ;COMPLAIN
+BACKUV:        POPJ    P,
+
+BCKTMP:        MOVSI   C,(C)
+       SUB     B,C             ; FIX UP POINTER
+       JUMPL   B,OUTRNG
+       MOVSI   A,TTMPLT
+       POPJ    P,
+
+BACKB: SKIPA   E,[TBYTE]
+BACKC: MOVEI   E,TCHSTR
+       PUSH    TP,A
+       PUSH    TP,B
+       ADDI    A,(C)           ; NEW LENGTH
+       HRLI    A,(E)
+       PUSH    P,A             ; SAVE COUNT
+       LDB     E,[300600,,B]   ;BYTE SIZE
+       MOVEI   0,36.           ;BITS PER WORD
+       IDIVI   0,(E)           ;DIVIDE TO FIND BYTES/WORD
+       IDIV    C,0             ;C/ WORDS BACK, D/BYTES BACK
+       SUBI    B,(C)           ;BACK WORDS UP
+       JUMPE   D,CHBOUN        ;CHECK BOUNDS
+
+       IMULI   0,(E)           ;0/ BITS OCCUPIED BY FULL WORD
+       LDB     A,[360600,,B]   ;GET POSITION FILED
+BACKC2:        ADDI    A,(E)           ;BUMP
+       CAIGE   A,36.
+       JRST    BACKC1          ;O.K.
+       SUB     A,0
+       SUBI    B,1             ;DECREMENT POINTER PART
+BACKC1:        SOJG    D,BACKC2        ;DO FOR ALL BYTES
+\f
+
+
+       DPB     A,[360600,,B]   ;FIX UP POINT BYTER
+CHBOUN:        MOVEI   C,-1(TP)
+       PUSHJ   P,BYTDOP                ; FIND DOPE WORD
+       HLRZ    C,(A)
+       SKIPGE  -1(A)           ; SKIP IF NOT REALLY AN ATOM
+       SUBI    C,3             ; ELSE FUDGE FOR VALUE CELL AND OBLIST SLOT
+       SUBI    A,-1(C)         ; POINT TO TOP
+       MOVE    C,B             ; COPY BYTER
+       IBP     C
+       CAILE   A,(C)           ; SKIP IF OK
+       JRST    OUTRNG
+       POP     P,A             ; RESTORE COUNT
+       SUB     TP,[2,,2]
+       POPJ    P,
+
+
+BACKA: LSH     C,1             ;NUMBER TIMES 2
+       HRLI    C,(C)           ;TO BOTH HALVES
+       SUB     B,C             ;FIX POINTER
+       MOVE    E,B             ;AND SAVE
+       PUSHJ   P,GETATO                ;LOOK A T TOP
+       CAMLE   B,E             ;COMPARE
+       JRST    OUTRNG
+       MOVE    B,E
+       POPJ    P,
+
+; COMPILER'S BACK
+
+CIBACK:        PUSHJ   P,CPTYEE
+       JUMPL   C,OUTRNG
+       CAIN    E,P2WORD
+       JRST    WTYPL
+       PUSHJ   P,@BCKTBL(E)
+       JRST    MPOPJ
+\f
+MFUNCTION STRCOMP,SUBR
+
+       ENTRY   2
+
+       MOVE    A,(AB)
+       MOVE    B,1(AB)
+       MOVE    C,2(AB)
+       MOVE    D,3(AB)
+       PUSHJ   P,ISTRCM
+       JRST    FINIS
+
+ISTRCM:        GETYP   0,A
+       CAIE    0,TCHSTR
+       JRST    ATMCMP          ; MAYBE ATOMS
+
+       GETYP   0,C
+       CAIE    0,TCHSTR
+       JRST    WTYP2
+
+       MOVEI   A,(A)           ; ISOLATR LENGHTS
+       MOVEI   C,(C)
+
+STRCO2:        SOJL    A,CHOTHE        ; ONE STRING EXHAUSTED, CHECK OTHER
+       SOJL    C,1BIG          ; 1ST IS BIGGER
+       ILDB    0,B
+       ILDB    E,D
+       CAIN    0,(E)           ; SKIP IF DIFFERENT
+       JRST    STRCO2
+       CAIL    0,(E)           ; SKIP IF 2D BIGGER THAN 1ST
+       JRST    1BIG
+2BIG:  MOVNI   B,1
+       JRST    RETFIX
+
+CHOTHE:        JUMPN   C,2BIG          ; 2 IS BIGGER
+SM.CMP:        TDZA    B,B             ; RETURN 0
+1BIG:  MOVEI   B,1
+RETFIX:        MOVSI   A,TFIX
+       POPJ    P,
+
+ATMCMP:        CAIE    0,TATOM         ; COULD BE ATOM
+       JRST    WTYP1           ; NO, QUIT
+       GETYP   0,C
+       CAIE    0,TATOM
+       JRST    WTYP2
+
+       CAMN    B,D             ; SAME ATOM?
+       JRST    SM.CMP
+       ADD     B,[3,,3]        ; SKIP VAL CELL ETC.
+       ADD     D,[3,,3]
+
+ATMCM1:        MOVE    0,(B)           ; GET A  WORD OF CHARS
+       CAME    0,(D)           ; SAME?
+       JRST    ATMCM3          ; NO, GET DIF
+       AOBJP   B,ATMCM2
+       AOBJN   D,ATMCM1        ; MORE TO COMPARE
+       JRST    1BIG            ; 1ST IS BIGGER
+
+
+ATMCM2:        AOBJP   D,SM.CMP        ; EQUAL
+       JRST    2BIG
+
+ATMCM3:        LSH     0,-1            ; AVOID SIGN LOSSAGE
+       MOVE    C,(D)
+       LSH     C,-1
+       CAMG    0,C
+       JRST    2BIG
+       JRST    1BIG
+
+\f;ERROR COMMENTS FOR SOME PRIMITIVES
+
+OUTRNG:        ERRUUO  EQUOTE OUT-OF-BOUNDS
+
+WRNGUT:        ERRUUO  EQUOTE TYPES-DIFFER-IN-UNIFORM-VECTOR
+
+IIGETP:        JRST    IGETP           ;FUDGE FOR MIDAS/STINK LOSSAGE
+IIPUTP:        JRST    IPUTP
+
+\f;SUPER USEFUL ERROR MESSAGES  (USED BY WHOLE WORLD)
+
+WNA:   ERRUUO  EQUOTE WRONG-NUMBER-OF-ARGUMENTS
+
+TFA:   ERRUUO  EQUOTE TOO-FEW-ARGUMENTS-SUPPLIED
+
+TMA:   ERRUUO  EQUOTE TOO-MANY-ARGUMENTS-SUPPLIED
+
+WRONGT:        
+WTYP:  ERRUUO  EQUOTE ARG-WRONG-TYPE
+
+IWTYP1:
+WTYP1: ERRUUO  EQUOTE FIRST-ARG-WRONG-TYPE
+
+IWTYP2:
+WTYP2: ERRUUO  EQUOTE SECOND-ARG-WRONG-TYPE
+
+BADTPL:        ERRUUO  EQUOTE BAD-TEMPLATE-DATA
+
+BADPUT:        ERRUUO  EQUOTE TEMPLATE-TYPE-VIOLATION
+
+WTYP3: ERRUUO  EQUOTE THIRD-ARG-WRONG-TYPE
+
+WTYPL: ERRUUO  EQUOTE INTERNAL-BACK-OR-TOP-OF-A-LIST
+
+WTYPUN:        ERRUUO  EQUOTE NON-STRUCTURED-ARG-TO-INTERNAL-PUT-REST-NTH-TOP-OR-BACK
+
+CALER1:        MOVEI   A,1
+CALER: HRRZ    C,FSAV(TB)
+       PUSH    TP,$TATOM
+       CAIL    C,HIBOT
+       SKIPA   C,@-1(C)        ; SUBRS AND FSUBRS
+       MOVE    C,3(C)          ; FOR RSUBRS
+       PUSH    TP,C
+       ADDI    A,1
+       ACALL   A,ERROR
+       JRST    FINIS
+  
+
+GETWNA:        HLRZ    B,(E)-2         ;GET LOSING COMPARE INSTRUCTION
+       CAIE    B,(CAIE A,)     ;AS EXPECTED ?
+       JRST    WNA             ;NO,
+       HRRE    B,(E)-2         ;GET DESIRED NUMBER OF ARGS
+       HLRE    A,AB            ;GET ACTUAL NUMBER OF ARGS
+       CAMG    B,A
+       JRST    TFA
+       JRST    TMA
+
+END
+\f
\ No newline at end of file