
      HED PROTECT 
* THE PROTECT COMMAND CAN BE USED BY A000 AND BY GROUP LIBRARIANS 
* TO RESTRICT THE USE OF PROGRAMS AND FILES BY OTHER USERS. 
* A PROTECTED PUBLIC OR GROUP LIBRARY PROGRAM MAY NOT BE LISTED,
* SAVED, CSAVED, OR PUNCHED IN ANY WAY BY ANOTHER USER.  A
* PROTECTED FILE MAY NOT BE ACCESSED AT ALL.  THE PROTECT 
* COMMAND SIMPLY SETS BIT 15 OF WORD 1 OF THE DIRECTORY ENTRY 
* FOR THE PROGRAM OR FILE.
      SPC 1 
      ORG LIBRA 
      SPC 1 
      LDB MLINK+1   GET USER'S ID 
      ADB .+?ID-?LINK 
      LDA B,I 
      STA LTEMP     PLACE ID INTO LTEMP 
      AND B1777     CHECK 
      CLB             FOR 
      DIV .100          PRIVILEGED
      SZB,RSS             USER
      JMP PRO1
* 
      LDA .-19
      LDB *+2 
      JMP LIBER 
      DEF *+1 
      OCT 5120      LF-P
      ASC 9,RIVILEGED COMMAND 
* 
PRO1  LDA DLTEM     SET POINTER TO PROGRAM NAME 
      STA PROC
      LDA .-3       SET UP COUNTER. 
      STA PROD
      JSB LCHAR     GET FIRST CHAR. 
      JMP PRO2      ERROR IF NONE.
PRO3  ALF,ALF       SAVE CHARACTER IN 
      ISZ PROC       TABLE. 
      STA PROC,I
      JSB LCHAR     GET RIGHT CHAR. 
      LDA .+40B     IF END CHANGE TO BLANK
      IOR PROC,I
      STA PROC,I
      JSB LCHAR     GET NEXT CHAR.
      LDA .+40B 
      ISZ PROD      DO WE WANT IT?
      JMP PRO3      YES.
      CPA .+40B     MUST BE A BLANK.
      JMP PRO4
* 
PRO2  LDA .-13
      LDB *+2 
      JMP LIBER 
      DEF *+1 
      OCT 5111      LF-I
      ASC 6,NVALID NAME 
* 
PRO4  JSB DLOKP,I   SEARCH FOR PROG IN DIRECTORY
      JMP PRO6      FOUND.
* 
      LDA .-14
      LDB *+2 
      JMP LIBER 
      DEF *+1 
      OCT 5116      LF-N
      ASC 6,O SUCH ENTRY
* 
PRO6  LDB LTEMP+5   SET PROTECT BIT.
      INB 
      LDA 1,I 
PRO7  IOR BIT15 
      STA 1,I 
      LDA DATIM     SET THE LAST
      ADB .+5         CHANGED DATE
      STA B,I 
* 
      LDB LTEMP+4   WRITE OUT DIRECTORY.
      LDA 1,I 
      STA MWORD 
      ADB .+5 
      LDA B 
      LDB LIBD
      JSB DISCZ,I 
      JSB SLVAG,I 
      JMP LLEND 
PROD  EQU LTEMP+6 
PROC  EQU LTEMP+7 
$PRO  EQU * 
      HED UNPROTECT 
* UNPROTECT IS IDENTICAL TO PROTECT EXCEPT THAT IT CLEARS THE 
* PROTECT BIT INSTEAD OF SETTING IT.
      ORG LIBRA 
      LDB MLINK+1 
      ORG PRO7
      ELA,CLE,ERA 
      HED OPEN
* THE OPEN COMMAND IS A USER FUNCTION WHICH CAUSES THE SYSTEM TO
* CREATE ROOM FOR A DATA FILE. THE FORMAT FOR THE COMMAND IS: 
* 
*     OPEN - FILENAME, FILE LENGTH, RECORD SIZE 
* 
* THE FILENAME IS SUBJECT TO ALL THE RULES OF PROGRAM NAMES. THE
* LENGTH IS A DECIMAL INTEGER FROM 1 TO 32767 INDICATING THE FILE 
* LENGTH IN RECORDS.  RECORD SIZE IS A DECIMAL INTEGER FROM 64 TO 
* 256 INDICATING THE RECORD SIZE IN WORDS.
      SPC 2 
      ORG LIBRA 
      LDA MLINK+1   GET ID AND STORE
      ADA .+?ID-?LINK    IN LTEMP.
      LDA 0,I 
      STA LTEMP 
      LDA DLTEM     SET UP POINTER FOR
      STA OPEP       NAME.
      LDA .-3       SET UP COUNTER. 
      STA OPEC
      CLA           SET FLAG SAYING FIRST 
      STA OPEF       CHAR.
OPE1  JSB OPER      GET A CHARACTER.
      ALF,ALF       STORE IN
      ISZ OPEP       NAME AREA. 
      STA OPEP,I
      JSB OPER      GET RIGHT CHAR. 
      IOR OPEP,I    MERGE IN. 
      STA OPEP,I
      ISZ OPEC      TEST FOR ANY MORE.
      JMP OPE1
* 
      JSB OPER      NEXT CHARACTER MUST BE
      CPA .+40B      BLANK. 
      JMP OPE2
      LDA .-14
      LDB *+2 
      JMP LIBER 
      DEF *+1 
      OCT 5116      LF-N
      ASC 6,AME TOO LONG
* 
OPER  NOP           GET NEXT CHAR FOR NAME. 
      LDA OPEF      TEST TO SEND BACK BLANK.
      CPA .+40B 
      JMP OPER,I
OPER1 JSB LCHAR     GET NEXT CHAR.
      JMP ILFER     FAIL IF NONE. 
      LDB 0         SAVE IN B.
      AND .140      SKIP CONTROL CHARS. 
      SZA 
      CPA .140
      JMP OPER1 
      LDA OPEF      GET 1ST CHAR. FLAG. 
      SZA           TEST FOR 1ST CHAR.
      JMP OPER2     NOT.
      CPB .+54B     TEST FOR COMMA OR $ 
      JMP ILFER 
      CPB .+44B 
      JMP OPE16 
      CPB .+52B     TEST FOR *
      JMP OPE16 
OPER3 LDA 1         RETURN CHAR IN B
      ISZ OPEF
      JMP OPER,I
OPER2 CPB .+54B     COMMA TEST
      RSS 
      JMP OPER3 
      LDA .+40B 
      STA OPEF
      JMP OPER,I
* 
OPE16 LDA .-24
      LDB *+2 
      JMP LIBER 
      DEF *+1 
      OCT 5111      LF-I
      ASC 11,LLEGAL FIRST CHARACTER 
* 
* GET FILE LENGTH.
* 
OPE2  CLA           INITIALIZE # TO 0 
      STA OPEF
      JSB LCHAR     GET A CHAR. 
      JMP OPE51     DONE
      CPA .+54B     IS IT A COMMA?
      JMP OPE50     YES, GO GET RECORD SIZE 
      ADA M72B      DIGIT TEST. 
      SSA,RSS 
      JMP ILFER 
      ADA .+10
      SSA 
      JMP ILFER 
      STA OPEC      SAVE DIGIT. 
      LDA OPEF
      JSB OPESB 
      JMP OPE2+1
* 
* GET RECORD SIZE 
* 
OPE50 CLA           INITIALIZE SIZE TO 0
      STA OPEP
      JSB LCHAR     GET A CHARACTER 
      JMP OPE3      DONE
      ADA M72B      DIGIT TEST
      SSA,RSS 
      JMP ILFER 
      ADA .+10
      SSA 
      JMP ILFER 
      STA OPEC      SAVE DIGIT
      LDA OPEP      BUILD 
      JSB OPESB 
      JMP OPE50+1   GET NEXT DIGIT
* 
OPE51 LDA B400      DEFAULT RECORD SIZE 
      STA OPEP        IS 256 WORDS
* 
* ERROR CHECK OF RECORD SIZE
* 
OPE3  LDA OPEF      TEST FOR LEGAL VALUE. 
      SSA,RSS 
      SZA,RSS 
      JMP ILFER     ERROR IF ZERO OR NEGATIVE 
      LDA OPEP      GET RECORD SIZE 
      ADA M64 
      SSA           LESS THAN 64? 
      JMP ILFER     YES, AND THAT'S NOT PLAYING 
*                                     BY THE RULES. 
      ADA OM193 
      SSA,RSS       GREATER THAN 256? 
      JMP ILFER     THAT'S EQUALLY A NO-NO
* 
* CHECK IDT FOR AVAILABLE SPACE 
* 
      JSB GCID,I    GET APPROPRIATE ID TRACK
      ADB .+6       TEST FOR USER OUT OF DISK SPACE 
      LDA 1,I 
      CMA,CLE 
      INB 
      ADA 1,I 
      ADA OPEF
      SEZ,RSS 
      JMP OPE4
* 
      LDB *+3 
      LDA .-19
      JMP LIBER 
      DEF *+1 
      OCT 5114      LF-L
      ASC 9,IBRARY SPACE FULL 
* 
* SEARCH ADT FOR SPACE TO PUT THE FILE. 
* 
OPE4  EQU * 
      LDA .-8       SET COUNT OF ADT'S TO SEARCH
      STA OPEDF 
OPE4A EQU * 
      LDA RKCYP     ADVANCE THE CURRENT 
      ADA .+3         ADT TRACK POINTER 
      CPA DALNA     CHECK FOR END OF TABLE
      LDA DALCA     CYCLE TO BEGINNING IF SO
      STA RKCYP 
      ADA .+ADTLN-ADTAT  => ADT LENGTH TABLE
      STA OPELN 
      LDA OPELN,I   IS THIS DISK
      SZA,RSS         AVAILABLE?
      JMP OPE6A     NO, TRY NEXT ADT
      STA MWORD     YES 
      LDA RKCYP     READ IN 
      LDB LIBDI       THE DISK ADT
      JSB DISCZ,I       TRACK 
      JMP OPE6A 
      CCB           COMPUTE 
      LDA OPELN,I     ENTRY 
      DIV .+3           COUNT 
      STA OPEC            AND SAVE
      LDB LIBD      => FIRST ENTRY
      ADB .+2         LENGTH WORD 
OPE6  LDA 1,I       TEST FOR BIG ENOUGH.
      CMA,CLE 
      ADA OPEF
      SEZ,RSS 
      JMP OPE5      IT IS.
      ADB .+3 
      ISZ OPEC
      JMP OPE6
OPE6A EQU * 
      ISZ OPEDF     HAVE WE TRIED ALL ADTS? 
      JMP OPE4A     NO, TRY NEXT ONE
* 
OPE12 EQU * 
      LDA .-16
      LDB *+2 
      JMP LIBER 
      DEF *+1 
      OCT 5123      LF-S
      ASC 7,YSTEM OVERLOAD
* 
* AT THIS POINT, SPACE HAS BEEN FOUND IN THE ADT
* 
OPE5  LDA OPEF      SAVE
      CMA,INA         -NUMBER 
      ADA B,I           OF SECTORS
      STA OPEDF           LEFT
      ADB .-2       SAVE LOCATION OF
      STB OPEC        DISC ADT ENTRY
      DLD 1,I       SAVE DISC 
      DST OPEDA       ADDRESS 
* 
* DOES THE ENTRY ALREADY EXIST? 
* 
      LDA LTEMP+2   SET 
      IOR BIT15     FILES 
      STA LTEMP+2   BIT 
      JSB DLOKP,I   SEARCH FOR ENTRY
      JMP OPE8      ENTRY FOUND--ILLEGAL. 
* 
* TEST FOR FULL DIRECTORY TRACK 
* 
      LDB LTEMP+4,I IF DIRECTORY TRACK IS 
      CPB M8184      FULL, DO 
      JMP OPE98       SUPERSAVE (THE SAVE OF STEEL) 
* 
* MAKE ROOM FOR THE NEW ENTRY IN THE DIRECTORY
* 
      CMB           SET UP SOURCE 
      ADB LIBD       FOR MOVE.
      STB MOVES 
      ADB .+12      SET UP DESTINATION
      STB MOVED 
      CMB           COMPUTE LENGTH. 
      ADB .+24
      ADB LTEMP+5 
      JSB MOVEB 
* 
* INSERT NEW ENTRY
* 
      LDA DLTEM     MOVE 4 WORDS IN FOR 
      STA MOVES      NEW ENTRY. 
      LDA LTEMP+5 
      ADA .+12
      STA MOVED 
      LDB .-4 
      JSB MOVEW 
      LDA OPEP      GET LOGICAL RECORD SIZE 
      STA MOVED,I     AND PUT IT IN DIRECTORY 
      ISZ MOVED     BUMP POINTER
      JSB DATE      GET DATE
      STA MOVED,I   SET IT IN LAST REFERENCE DATE 
      ISZ MOVED 
      LDA DATIM     GET HOUR OF YEAR
      STA MOVED,I   SET IT IN LAST CHANGE DATE
      ISZ MOVED 
      CLA 
      STA MOVED,I 
      ISZ MOVED 
      DLD OPEDA     GET DISC ADDRESS
      DST MOVED,I     INTO DIRECTORY
      LDA .+3       INSERT FILE 
      ADA MOVED       LENGTH INTO 
      LDB OPEF          LAST WORD OF
      STB A,I             DIRECTORY ENTRY 
* 
      LDA LTEMP+4,I ADJUST DIRECTORY
      ADA .-12       LENGTH 
      STA LTEMP+4,I 
      STA MWORD 
      LDA LTEMP+4   WRITE DIRECTORY 
      INA            BACK OUT.
      STA MOVED 
      ADA .+4 
      LDB LIBD
      STB MOVES 
      JSB DISCZ,I 
      JSB DEADP,I 
* 
      LDB .-4       RESET 
      JSB MOVEW      DIREC. 
* 
* UPDATE THE ADT AND IDT
* 
OPE11 EQU * 
      JSB GCID,I    GET ID TRACK AGAIN
      ADB .+7 
      LDA OPEF      ADJUST AMOUNT OF DISC USED. 
      ADA 1,I 
      STA 1,I 
      LDA IDTAD     WRITE 
      LDB LIBD        OUT 
      JSB DISCZ,I       IDT 
      JSB DEADP,I 
      LDA OPELN,I   READ
      STA MWORD       IN
      LDA RKCYP         DISC
      LDB LIBDI           ADT 
      JSB DISCZ,I      TRACK
      JMP OPE14 
* 
      LDB OPEDF     GET -# OF SECTORS LEFT IN ADT.
      SZB           REST FOR ANY PART LEFT
      JMP OPE9      NON EMPTY ADT ENTRY.
* 
      LDB OPEC      SQUEEZE OUT ADT ENTRY.
      STB MOVED 
      ADB .+3 
      STB MOVES 
      ADB MLIBD 
      ADB MWORD 
      JSB MOVEW 
* 
      LDA .+3       REDUCE
      LDB OPELN,I     DISC ADT
      ADB A             LENGTH
      STB OPELN,I         BY 3
      ADA MWORD     ALSO REDUCE 
      STA MWORD       TRANSFER LENGTH 
      JMP OPE10 
* 
OPE9  DLD OPEC,I    UPDATE
      CLE 
      ADB OPEF        DISC
      SEZ 
      INA               ADDRESS 
      DST OPEC,I
      LDB OPEC      SAVE
      ADB .+2         REMAINING 
      LDA OPEDF         BLOCKS
      STA B,I             LENGTH
* 
OPE10 EQU * 
      LDA RKCYP     WRITE 
      LDB LIBD        DISC ADT
      JSB DISCZ,I       BACK
      JMP OPE14 
* 
* FILL FILE WITH EOF MARKS
* 
OPE15 LDB M40       FILL
      STB OPEC       USER 
      LDB LIBD        AREA
      CCA              WITH 
      STA B,I           END-
      ADB B400           OF-
      ISZ OPEC            FILE
      JMP *-3              MARKS
* 
      LDA .-10      INITIALIZE WRITES-BEFORE- 
      STA OPEC        SUSPEND COUNT 
      LDA M10K      INITIALIZE
      STA MWORD       WORD COUNT
* 
OPE52 LDB OPEF      GET REMAINING RECORD COUNT
      ADB M40       MORE THAN 
      SSB             40? 
      JMP OPE13     NO, GO DO PARTIAL WRITE 
      STB OPEF      YES, UPDATE COUNT 
      LDA OPEDI     POINTER TO DISC TO DISC ADDRESS 
      LDB LIBD      CORE ADDRESS
      JSB DISCZ,I   WRITE 40 FILE MARKS 
      JMP OPEDE     FAILURE: GO PRINT ERROR 
      DLD OPEDA     UPDATE
      CLE 
      ADB .+40        DISC
      SEZ 
      INA               ADDRESS 
      DST OPEDA 
* 
      ISZ OPEC      TIME TO SESPEND?
      JMP OPE52     NO, CONTINUE
* 
*     AFTER 10 WRITES OF 40 FILE MARKS EACH, SUSPEND. 
* 
      LDB MLINK+1        GET POINTER TO DISC
      ADB .+?RTIM-?LINK    ADDRESS STORAGE
      LDA OPEDA+1        GET LOW PART AND 
      STA B,I              STASH IN TTY TABLE 
      INB 
      LDA LTEMP+1   STORE 
      STA B,I        ALSO 
      INB             FILE
      STB OPEC         NAME 
      DLD LTEMP+2       IN TTY
      DST OPEC,I         TABLE
      CLF 0              DISABLE INTERRUPTS 
      LDB MLINK+1        SET
      ADB .+?PLEV-?LINK   PRIORITY
      LDA .+4         TO
      STA B,I          4
      ADB .+?RSTR-?PLEV  SET
      LDA OP17P           RESTART 
      STA B,I              ADDRESS
      CLA                BLOCK
      STA DCLC1,I         CLOCK 
      STF 0         ENABLE INTERRUPTS 
      LDB MLINK+1   REMOVE
      LDA B,I         USER
      STA MLINK+1       FROM Q
      JSB INSEQ     AND REINSERT HIM (OR HER) 
      JMP *+1,I     GO TO 
      DEF SCH1        SCHEDULER 
* 
* 
*     OPEN WILL BE RESTARTED HERE.
* 
OPE17 LDB MLINK+1        GET
      ADB .+?ID-?LINK     USER
      LDA B,I              ID 
      STA LTEMP 
      ADB .+?RTIM-?ID    GET LOW
      LDA B,I             WORD OF CURRENT 
      STA OPEDA+1          DISC ADDRESS 
      INB 
      LDA B,I            GET
      STA LTEMP+1         FILE
      INB                  NAME 
      DLD B,I               BEING 
      DST LTEMP+2            INITIALIZED
* 
      JSB DLOKP,I   CHECK FOR FILE'S EXISTENCE
      RSS           IT'S THERE
      JMP LLEND     IT'S GONE: TERMINATE
      LDB LTEMP+5   GET 
      ADB .+2        WORD 
      LDA B,I         2 
      SSA,RSS       IS IT A FILE? 
      JMP LLEND     NO, TERMINATE 
      ADB .+6       => DISC ADDRESS 
      LDA B,I       SET TENTATIVE UPPER 
      STA OPEDA       WORD OF CURRENT DISC ADDRESS
      STB OPEC      SAVE DISC 
      ADB .+3        ADDRESS AND
      STB OPEP        LENGTH POINTERS 
      JSB OPERC     CHECK CURRENT FOR IN RANGE
      JMP OPE18     IT IS: PROCEED
      ISZ OPEDA     TRY ONE HIGHER UPPER WORD 
      JSB OPERC     AGAIN CHECK FOR IN RANGE
      RSS           GOOD
      JMP LLEND     BAD, GIVE UP
OPE18 CMB,INB       GET REMAINING RECORD
      STB OPEF        COUNT AND STORE 
      JMP OPE15     GO WRITE SOME FILE MARKS
* 
OPERC NOP 
      DLD OPEC,I    GET FILE START
      JSB OPEDS     SUBSTRACT IT FROM CURRENT ADDRESS 
      CLE,SSA       IN RANGE? 
      JMP OPE19     NO, GO FAIL 
      DLD OPEC,I    GET FILE START
      ADB OPEP,I    CALCULATE DISC
      SEZ             ADDRESS OF ONE
      INA               BEYOND FILE END 
      JSB OPEDS     SUBTRACT IT FROM CURRENT ADDRESS
      SSA,RSS       IN RANGE? 
OPE19 ISZ OPERC     NO, BUMP RETURN 
      JMP OPERC,I 
* 
* 
OPEDS NOP 
      CMB,CLE,INB   NEGATE
      CMA,SEZ         A,B 
      INA               CONTENTS
      CLE 
      ADB OPEDA+1   ADD 
      SEZ             TO
      INA               OPEDA, OPEDA+1
      ADA OPEDA           CONTENTS
      JMP OPEDS,I 
* 
* 
OPE13 EQU * 
      LDB OPEF      GET RECORDS LEFT
      SZB,RSS       IF NONE,
      JMP LLEND       DON'T BOTHER
      BLF,BLF         NUMBER OF 
      CMB,INB           WORDS TO
      STB MWORD           TRANSFER
      LDA OPEDI     WRITE 
      LDB LIBD        OUT TO
      JSB DISCZ,I       DISC
      JMP OPEDE     UNSUCCESSFUL DISK TRANSFER
      JMP LLEND     TERMINATE 
* 
OPE14 CLA 
      CLB 
      STB OPELN,I 
      DST RKCYP,I 
      JMP OPE15 
* 
OPESB NOP 
      MPY .+10      BUILD NEW 
      CLE            NUMBER.
      ADA OPEC
      SEZ,SZB,RSS   OVERFLOW CHECK. 
      JMP OPESB,I   EXIT
      JMP ILFER 
OPEDE EQU * 
      LDA OM31      GET CHARACTER COUNT 
      LDB *+2         AND POINTER 
      JMP LIBER 
      DEF *+1 
      OCT 5125
      ASC 15,NSUCCESSFUL; KILL AND REPEAT.
* 
OPE8  EQU * 
      LDA .-16
      LDB *+2 
      JMP LIBER 
      DEF *+1 
      OCT 5104
      ASC 7,UPLICATE ENTRY
* 
OPE98 EQU * 
      LDA OM507     SET UP OVERLAY
      STA MWORD 
      LDA OPEOV 
      LDB #LIBI 
      JMP OPEOR 
M10K  DEC -10240
OM507 DEC -507
OM193 DEC -193
M40   DEC -40 
OM31  DEC -31 
* 
OPEDA EQU LTEMP+6   DISC
*                         LTEMP+7     ADDRESS 
OPEF  EQU LTEMP+8 
OPEDF EQU LTEMP+9   COUNTER 
OPEP  EQU LTEMP+10
* OPEP IS REFERRED TO AS SAVP BY SUPERSAVE (AND SAVE) 
OPEC  EQU LTEMP+11
OPELN EQU LTEMP+12  => ADT LENGTH TABLE 
* 
* LTEMP THROUGH LTEMP+5 ARE ALSO USED 
* 
OP17P DEF OPE17 
OPEOV DEF COM6+SAVO-COM3+SAVO-COM3
OPEDI DEF OPEDA 
DALCA DEF ADTAT 
DALNA DEF DKTBL     END OF ADT TABLE
* 
      ORG LIBRA+507 
OPEOR JSB DISCZ,I 
      JSB SICKP,I 
      JMP LIBRA 
      JMP OPE11     NORMAL RETURN.
      JMP OPE12     ERROR RETURN
$OPE  EQU * 
