      HED CHAIN 
* DHE CHAIN ROUTINE IS USED BY THE BASIC COMPILER TO PROCESS A CHAIN
* STATEMENT DURING PHASE III. THE PURPOSE OF THIS ROUTINE IS TO 
* CHECK FOR THE REQUESTED PROGRAM ON THE USER'S PRIVATE LIBRARY OR
* ON THE PUBLIC LIBRARY (IF THE NAME IS PRECEDED BY A DOLLAR SIGN)
* IF THE PROGRAM IS FOUND IT IS LOADED AND COMPILATION IS BEGUN.
      ORG LIBRA 
      LDA FCNTR     SET COUNTER TO
      CMA             1'S COMPLEMENT OF 
      STA FCNTR         NUMBER OF FILES 
      LDA FCORE     LOAD FIRST BUFFER ADDRESS 
      LDB FILTB     LOAD POINTER TO 
      ADB .+2         FIRST DISC ADDRESS
CHN01 ISZ FCNTR     MORE FILES? 
      RSS           YES 
      JMP CHAN0     NO--FINISHED DUMPING BUFFERS
      STB FBASE     WRITE 
      STA RQ3         OUT 
      JSB WRBUF         RECORD
      LDA RQ3       MOVE
      ADA B200        POINTERS
      LDB FBASE         FOR NEXT
      ADB .+7             FILE
      JMP CHN01 
CHAN0 LDB MLINK+1 
      ADB .+?ID-?LINK 
      STB CHNI      => USER ID
      LDA 1,I 
      STA LTEMP    STORE IN LTEMP 
      LDA DLTEM    SET UP 
      INA            POINTER
      STA CHNP         FOR NAME 
      LDA TEMP1     LOAD POINTER TO FIRST WORD
      ALS           DOUBLE FOR CHARACTER POINTER
      INA           TO RIGHT CHARACTER
      STA CHNC      STORE PICKUP POINTER
      LDA .-7 
      STA INCHR     SET STORE COUNTER 
      LDA OUTWR 
      STA OUTWD     SET STORE POINTER 
      CCA           A = -1
      ADA TEMP1     A => LENGTH WORD
      LDA 0,I       LOAD LENGTH 
      ADA .-3 
      ALS 
      CMA 
      STA INWRD     SET PICKUP COUNTER
      JSB CHNCH     GET A CHARACTER              B] 
      CPA .+42B    QUOTE? 
      RSS          YES  GET NEXT CHAR 
      JMP CHAN7+1   NO ERROR
      JSB CHNCH 
      SZA,RSS    IS CHARACTER OK? 
      JMP CHAN7+1   NO
      CPA .+44B     CHECK FOR DOLLARS SIGN
      JMP CHAN2     $ 
CHAN3 EQU * 
      STA OUTWD,I   STORE CURRENT CHARACTER 
      ISZ OUTWD     COUNT UP STORE POINTER
      ISZ INCHR     COUNT UP STORE COUNTERS 
      JMP CHAN1 
      JMP CHAN7+1   INVALID NAME
CHAN2 EQU * 
      LDA A000      SET UP FOR PUBLIC SEARCH
      STA LTEMP 
      ISZ INWRD     CHECK PICKUP COUNTER
      JMP CHAN1+3 
      JMP CHAN7+1   INVALID NAME
CHAN1 EQU * 
      ISZ INWRD     CHECK PICKUP COUNTER
      RSS 
      JMP CHAN4     JUMP IF DONE WITH INPUT STRING
      JSB CHNCH     GET A CHARACTER              B] 
      SZA,RSS     END OF STRING?
      JMP CHAN7+1  YES - NO CLOSE QUOTE 
      CPA .+42B    CLOSE QUOTE? 
      RSS         YES - END OF NAME 
      JMP CHAN3   NO - PROCESS CHAFACTER
CHAN4 EQU * 
      LDA .+40B     GET BLANK 
      STA OUTWD,I   STORE INTO BUFFER 
      ISZ OUTWD     COUNT UP BUFFER POINTER 
      ISZ INCHR     COUNT UP BUFFER COUNTER 
      JMP CHAN4+1 
      ISZ SCHLQ     PAST FIRST TYPE OF ERROR
      LDB .-3 
      STB PKCNT     3 WORDS TO PACK 
      LDA OUTWR 
      STA OUTWD 
CHAN5 LDA OUTWD,I 
      ALF,ALF       LEFT HALF 
      ISZ OUTWD 
      IOR OUTWD,I   RIGHT HALF
      STA CHNP,I    STORE IT
      ISZ CHNP
      ISZ OUTWD 
      ISZ PKCNT     THREE WORDS FINISHED? 
      JMP CHAN5     NO
      LDA SPROG 
      STA INWRD 
      JSB DLOOK    SEARCH DIRECTORY FOR PROGRAM 
      RSS 
      JMP CHAN7     PROGRAM NOT FOUND 
      ISZ SCHLQ     PAST SECOND ERROR 
      LDB CHNPD 
      ADB .+2 
      LDA 1,I I
      SSA Au
      JMP CHAN7     ENTRY IS A FILE 
      ISZ SCHLQ     PAST THIRD ERROR
* 
* FOUND CORRECT ENTRY. FIRST CHECK TO SEE IF IT FITS
* 
      ADB .+2                                    X] 
      LDA 1,I       SAVE START-OF-
      STA LIBSP       PROGRAM POINTER 
      ADB .+3       GET PROGRAM LENGTH
      LDA 1,I 
      STA CHNLN 
      CMA,INA      COMPUTE FIRST
      ADA LIBSP       UNUSED WORD 
      STA LIBPB 
      CMA,INA      COMPUTE NEGATIVE 
      ADA U4475     TOTAL LENGTH
      SSA           COMPARE WITH MAX ALLOWED
      JMP CHAN7     PROGRAM TOO LARGE 
      JSB DATE     SET NEW DATE 
      LDB CHNPD      INTO 
      ADB .+5          DIRECTORY
      STA 1,I 
      INB          SET PROGRAM
      LDA 1,I        DISC ADDRESS 
      STA CHND
      LDA CHNP,I   WRITE DIRECTORY
      STA WORD       BACK TO
      LDA CHNP         DISC 
      ADA .+6 
      LDA 0,I 
      LDB LIBD
      JSB DISCL 
      LDA CHNI,I   GET USER'S ID
      ISZ CHNPD    BUMP POINTERS UP 
      ISZ CHNI       TO FIRST WORD OF NAME
      LDB CHNPD,I 
      CPA A000     IF SYSTEM MASTER CLEAR 
      ELB,CLE,ERB    RUN-ONLY BIT 
      STB CHNI,I   STORE FIRST WORD OF NAME 
      ISZ CHNI     BUMP POINTER TO NEXT WORD
      DLD LTEMP+2  GET LAST 2 WORDS OF NAME 
      DST CHNI,I   STORE IN TABLE 
      LDB MLINK+1  SET TO NULL PROGRAM
      ADB .+?PROG-?LINK 
      LDA INWRD 
      STA 1,I 
      JSB RDPRG    READ IN FIXED AREA 
      LDA CHNLN     SET UP TRANSFER FOR 
      STA WORD       READING IN PROGRAM 
      LDA CHND
      LDB LIBSP     => START OF PROGRAM 
      ADB BIT15 5
      JSB DISCL    APPEND LIBRARY PROGRAM 
      JSB SEMIC 
      JSB ABCK,I    ABORT?
* 
* SET TO RUN
* qq
      CLF 0 
      LDB MAIN
      ADB .+?TSTA  DON'T
      LDA 1,I 
      IOR UNABT      ALLOW
      STA 1,I 
      ADB .-?TSTA+?STAT  ABORTS 
      ISZ 1,I       SET STATUS TO RUN 
      ISZ TIMEF    SET FLAG FOR TIMING
      LDB SPROG     NULL
      CPB PBPTR       PROGRAM?
      JMP CHAN6     YES 
      STB PRGCT     SET PROGRAM COUNTER 
      LDA .+40B     TURN ON 
      STA BLANK       BLANK SUPPRESSION 
      LDB MAIN     SET THE CHAIN                 X] 
      ADB .+?MASK  FLAG FOR THIS USER            X] 
      LDA CHNFG                                  X] 
      IOR 1,I                                    X] 
      STA CHNFG                                  X] 
      ADB .-?MASK+?CLOC 
      ISZ 1,I       BUMP USER'S TIMEOUT CLOCK 
      JMP CHAN8 
      ADB .+?PLEV-?CLOC 
      LDA .+4       SET PRIORITY TO 4 
      STA 1,I 
      ADB .+?RSTR-?PLEV 
      LDA CHNRT     SET RESTART ADDRESS 
      STA 1,I         TO COMPILER 
      CLA           BLOCK 
      STA DCLC1,I     CLOCK 
      STF 0         ENABLE INTERRUPT
      LDB MLINK+1 
      LDA 1,I       REMOVE  USER
      STA MLINK+1     FROM QUEUE
      JSB INSEQ     INSERT HIM AGAIN AT END 
      JMP *+1,I     JUMP TO SCHEDULER 
      DEF SCH1
CHAN6 STF 0         ENABLE INTERRUPT
      JMP *+1,I 
      DEF EXIT3 
CHAN7 JSB RDPRG     READ BACK USER PROGRAM
      JSB ABCK,I    ABORT?
      JMP SCHBL     NON.
CHAN8 STF 0 
      JMP CHNRT,I 
CHNCH NOP                                        B] 
      LDA CHNC      LOAD PICKUP POINTER 
      CLE,ERA 
      LDA 0,I       LOAD WORD WITH CURRENT CHARACTER
      SEZ,RSS       SKIP IF RIGHT CHARACTER 
      ALF,ALF 
      AND B177      MASK OFF CURRENT CHARACTER
      ADA M96                                    B] 
      SSA,RSS       SKIP IF UPPER CASE           B] 
      ADA M32       MAKE INTO UPPER CASE         B] 
      ADA .140      RESTORE CHARACTER            B] 
      ISZ CHNC      INCREMENT PICKUP POINTER
      JMP CHNCH,I                                B] 
CHNRT DEF CMPL0 
PKCNT BSS 1 
INWRD BSS 1 
INCHR BSS 1 1
OUTWR DEF OUTWD+1 
OUTWD BSS 8 
CHNP  EQU LTEMP+4 
CHNPD EQU LTEMP+5 5j
CHNI  EQU LTEMP+6 
CHNC  EQU LTEMP+7 
CHNLN EQU LTEMP+10
CHND  EQU LTEMP+12
$CHN  EQU * 
      HED  SAVE 
* THE SAVE COMMAND IS USED TO SAVE PROGRAMS IN THE USER LIBRARY.
* THE PROCEDURE IS AS FOLLOWS:
*     1) CHECK THAT PROGRAM IS LISTABLE (OR ID=A000), HAS A NAME, 
*        AND ISN'T NULL.
*     2) DECOMPILE. 
*     3) CHECK FOR IDT OR ADT OVERFLOW. 
*     4) CHECK FOR DUPLICATELY NAMED PROGRAM. 
*     5) UPDATE DIRECTORY.
*     6) UPDATE IDT AND ADT.
*     7) MOVE PROGRAM TO LIBRARY AREA.
* 
* STEP 5 IS WRITTEN AS AN OVERLAY, WHICH IS CALLED WHENEVER THE PAR-
* TICULAR DIRECTORY TRACK NEEDED IS ALREADY FULL. ITS JOB IS TO GAR-
* BAGE COLLECT THE DIRECTORY TRACKS.
      SPC 2 
      ORG LIBRA 
      SPC 1 1
      LDB MLINK+1   B=>LINK WORD. 
      ADB .+?ID-?LINK  ID LOCN. 
      STB MOVES 
      LDA 1,I 
      STA IDI 
      ADB .+?PROG-?ID 
      STB SAVPV

      ADB .+?DISC-?PROG 
      STB SAVD
      DLD MOVES,I   A=ID,B=1ST WORD OF NAME.
      SZB        TEST FOR NO PROGRAM NAME 
      CPB ASCBB 
      JMP SAV3
      LDB SAVP,I    TEST FOR NULL PROGRAM.
      LDA .-11
      CPB PBUFF 
      JMP SAV4
      JSB RDPRG         READ INTO CORE              [X] 
* 
      LDB SAVP      TEST FOR COMPILED.
      ADB .+?MASK-?PROG 
      LDA 1,I 
      AND CFLAG 
      SZA           PROGRAM COMPILED? 
* 
      JSB DCMPL     DECOMPILE IT. 
      LDB SPROG     ANY COMMON ALLOCATED? 
      CPB PBUFF                                     [X] 
      JSB ALCOM     NO - GO DO IT 
      LDA PBPTR     RESET PROGRAM BOUND 
      STA SAVP,I     INTO TABLE.
      CMA,INA       COMPUTE # OF
      ADA USE        WORDS. 
      STA WORD
      LDA SAVD,I    GET DISC ADDRESS. 
      LDB USE       WRITE OUT TO
      JSB DISCL      DISC.
* 
      LDB SAVP,I   COMPUTE -PROGRAM LENGTH
      CMB,INB 
      ADB SPROG      ADD PROG POINTER 
      STB SAVWD     SAVE IN WORDS 
      ASR 7        AND                           X] 
      STB SAVLN       SECTORS.
      LDB SPROG      SET PROGRAM POINTER            [X] 
      STB SAVP       INTO SAVP  FOR LATER           [X] 
* 
      JSB FIDT       FIND ID ENTRY
      ADB .+7       GET DISC USED TO DATE.
      LDA 1,I 
      CMA,INA       GET TOTAL AMNT TO BE USED AS
      ADA SAVLN      NEGATIVE.
      ADB .-1 
      CLE 
      ADA 1,I       COMPARE WITH ALLOTMENT. 
      SEZ 
      JMP SAV6      OK. 
      LDB *+3 3
      LDA .-16
      JMP LIBER 
      DEF *+1 
      OCT 5106      LF-F
      ASC 7,ILE SPACE FULLLZ
* 
* SEARCH ADT FOR SPACE TO PUT THE PROGRAM.
* 
SAV6  LDA MOVES,I  LOAD ID
      STA LTEMP    SAVE FOR FDISC 
      JSB FDISC    GO FIND DISC SPACE 
      LDA DLTEM    LOAD POINTER TO NAME 
      STA MOVED      LTEMP(0:3).
      LDB .-4 
      JSB MOVEW 
      JSB DLOOK     SEARCH FOR ENTRY. 
      JMP SAV12     ENTRY FOUND--ILLEGAL. 
SAV97 EQU * 
      JSB FDIRC    COMPUTE DIRECTORY
      LDA LTEMP    SET BIT 15                    X] 
      IOR BIT15      OF ID                       X] 
      STA LTEMP    SET UP TO                     X] 
      LDA LTEMP+4,I   LOAD TRACK LENGTH               [X] 
      SZA,RSS     IF ZERO  THEN NEXT TRACK            [X] 
      JMP SAV72                                       [X] 
      LDA DLTEM    COMPARE                       X] 
      LDB LTEMP+4  ENTRIES                       X] 
      INB                                        X] 
      JSB DIRCM    IS ENTRY ON THIS TRACK?       X] 
      JMP SAV72    NO                            X] 
SAV73 JSB DLOOK    YES, GO FIND IT               X] 
      NOP                         T               X]
* 
      LDB SAVI,I    IF TRACK IS FULL, GO DO 
      CPB S4560                                   (D) 
      JMP SAV98 
      CMB           SET UP SOURCE FOR 
      ADB LIBD       MOVE.
      STB MOVES 
      ADB .+8       SET UP DESTINATION. 
      STB MOVED 
      CMB           COMPUTE LENGTH. 
      ADB .+16
      ADB SAVS
      JSB MOVEB 
* 
      LDA LTEMP    LOAD ID  AND CLEAR BIT 15        [X] 
      ELA,CLE,ERA                                   [X] 
      STA LTEMP                                     [X] 
      LDA DLTEM     MOVE 5 WORDS IN FOR 
      STA MOVES      NEW ENTRY. 
      LDA SAVS
      ADA .+8 
      STA MOVED 
      LDB .-4 4W
      JSB MOVEW 
      LDA SAVP       SET PROGRAM START              [X] 
      STA MOVED,I    INTO DIRECTORY                 [X] 
      JSB DATE      STORE DATE IN ALSO. 
      ISZ MOVED 
      STA MOVED,I 
      ISZ MOVED 
      LDA SAVDS     INSERT DISC ADDRESS AND 
      LDB SAVWD      LENGTH.
      DST MOVED,I 
* 
      LDA SAVI,I    ADJUST
      ADA .-8        DIRECTORY
      STA SAVI,I      LENGTH. 
      STA WORD
      LDA SAVI      WRITE DIRECTORY BACK OUT. 
      INA 
      STA MOVED 
      ADA .+5 uS
      LDA 0,I 
      LDB LIBD
      STB MOVES 
      JSB DISCL 
* 
      LDB .-4       RESET DIREC.
      JSB MOVEW 
* *q
      JSB FIDT      FIND ID ENTRY 
      ADB .+7 zz
      LDA SAVLN     ADJUST AMOUNT 
      CMA,INA        OF DISC
      ADA 1,I         USED. 
      STA 1,I 
      LDA IDTRA,I    OURPUT ID TRACK TO DISC
      LDB LIBD
      JSB DISCL 
      LDA ADLEN      INPUT AD TABLE 
      STA WORD
      LDA ADLOC 
      LDB LIBDI 
      JSB DISCL 
* 
      LDB SAVDF     GET NEW ADT ENTRY LENGTH
      LDA SAVLN     COMPUTE NEW ADT ENTRY LOC.
      CMA,INA 
      ADA SAVA,I
      DST SAVA,I    SET NEW ADT ENTRY.
      SZB           TEST FOR ADT ENTRY ALL USED.
      JMP SAV22     NO--GO TO WRITE TO DISC.
* 
      LDB SAVA      SQUEEZE OUT ADT ENTRY.
      STB MOVED     DESTINATION IS LOC OF ENTRY 
      ADB .+2        BEING REMOVED; SOURCE IS 
      STB MOVES       NEXT ENTRY. 
      ADB MLIBD     B=# WORDS PRECEDING.
      ADB WORD      B=-# OF WORDS TO MOVE.
      JSB MOVEW W

* 
      ISZ ADLEN     REDUCE SIZE OF ADT BY 2 WORDS.
      ISZ ADLEN 
      ISZ WORD      REDUCE # OF WORDS TO WRITE OUT
      ISZ WORD       BY TWO.
SAV22 LDA ADLOC      WRITE ADT TO DISC
      LDB LIBD
      JSB DISCL 
* 
      JSB RDPRG     READ USER PROGRAM AGAIN.
      LDA SAVWD     WRITE IT OUT. 
      STA WORD       TO LIBRARY.
      LDA SAVDS       AREA. 
      LDB SAVP
      JSB DISC,I
* 
      JMP LLEND 
* 
* *q
SAV72 LDB LTEMP+4  GO BACK TO FIRST              X] 
      ADB .-7        TRACK                       X] 
      STB LTEMP+4                                X] 
      INB                                        X] 
      LDA DLTEM                                  X] 
      JSB DIRCM    IS ENTRY ON THIS TRACK?       X] 
      JMP SAV74    NO, MAKE IT THE FIRST ONE     X] 
      JMP SAV73                                  X] 
      JMP SAV73                                  X] 
SAV74 LDB LTEMP+4    LOAD THE                        [X]
      LDA 1,I     CORRECT                            [X]
      STA WORD                                        [X] 
      ADB .+6        DIRECTORY TRACK INTO            [X]
      LDA 1,I           BEFORE WE                     [X] 
      LDB LIBDI              START MOVING THINGS      [X] 
      JSB DISCL                                      [X]
      LDA LIBD                                       [X]
      ADA .-8        ADDRESS TO THE FRONT        X] 
      STA SAVS                                   X] 
      JMP SAV73+2                                   X]
* qq
S4560 DEC -4560                                   (D) 
* 
SAV98 LDA M252 LOAD SUPERSAVE 
      STA WORDR
      LDA SAVOV,I 
      LDB #LIBI 
      JMP LIBRA+252 
SAV3  LDA .-16
SAV4  LDB *+2 //
      JMP LIBER 
      DEF *+1 
      OCT 5116      LF-N
      ASC 7,O PROGRAM NAME
* 
SAV12 EQU * 
      LDA .-16
      LDB *+2 
      JMP LIBER 
      DEF *+1 
      OCT 5104
      ASC 7,UPLICATE ENTRY
* 
SAVI   EQU LTEMP+4
SAVS  EQU LTEMP+5 
SAVDS EQU LTEMP+6 
SAVWD EQU LTEMP+7 
SAVA  EQU LTEMP+8 
SAVP  EQU LTEMP+101/
SAVD  EQU LTEMP+11
SAVDF EQU LTEMP+12
SAVLN EQU LTEMP+13
* 
SAVOV DEF SAVE+1+COM6-COM3
* *q
      ORG LIBRA+252 
      JSB DISCL 
      JMP LIBRA 
      JMP SAV97 
$SAV  EQU * *,
