 (*$U-,S+*)

     (******************************************************************)
     (*                                                                *)
     (*  Copyright (c) 1978 Regents of the University of California.   *)
     (*  Permission to copy or distribute this software or documen-    *)
     (*  tation in hard or soft copy granted only by written license   *)
     (*  obtained from the Institute for Information Systems.          *)
     (*                                                                *)
     (******************************************************************)

 PROGRAM PASCALSYSTEM;

 (************************************************)
 (*                                              *)
 (*    UCSD PASCAL OPERATING SYSTEM              *)
 (*                                              *)
 (*    RELEASE LEVEL:  I.3   AUGUST, 1977        *)
 (*                      I.4   JANUARY, 1978     *)
 (*                    I.5   SEPTEMBER, 1978     *)
 (*                                              *)
 (*    WRITTEN BY ROGER T. SUMNER                *)
 (*    WINTER 1977                               *)
 (*                                              *)
 (*    INSTITUTE FOR INFORMATION SYSTEMS         *)
 (*    UC SAN DIEGO, LA JOLLA, CA                *)
 (*                                              *)
 (*    KENNETH L. BOWLES, DIRECTOR               *)
 (*                                              *)
 (************************************************)

 CONST
      MMAXINT = 32767;   (*MAXIMUM INTEGER VALUE*)
      MAXUNIT = 12;      (*MAXIMUM PHYSICAL UNIT # FOR UREAD*)
      MAXDIR = 77;       (*MAX NUMBER OF ENTRIES IN A DIRECTORY*)
      VIDLENG = 7;       (*NUMBER OF CHARS IN A VOLUME ID*)
      TIDLENG = 15;      (*NUMBER OF CHARS IN TITLE ID*)
      MAXSEG = 15;       (*MAX CODE SEGMENT NUMBER*)
      FBLKSIZE = 512;    (*STANDARD DISK BLOCK LENGTH*)
      DIRBLK = 2;        (*DISK ADDR OF DIRECTORY*)
      AGELIMIT = 300;    (*MAX AGE FOR GDIRP...IN TICKS*)
      EOL = 13;          (*END-OF-LINE...ASCII CR*)
      DLE = 16;          (*BLANK COMPRESSION CODE*)

 TYPE

      IORSLTWD = (INOERROR,IBADBLOCK,IBADUNIT,IBADMODE,ITIMEOUT,
                  ILOSTUNIT,ILOSTFILE,IBADTITLE,INOROOM,INOUNIT,
                  INOFILE,IDUPFILE,INOTCLOSED,INOTOPEN,IBADFORMAT,
                  ISTRGOVFL);

                                         (*COMMAND STATES...SEE GETCMD*)

      CMDSTATE = (HALTINIT,DEBUGCALL,
                  UPROGNOU,UPROGUOK,SYSPROG,
                  COMPONLY,COMPANDGO,COMPDEBUG,
                  LINKANDGO,LINKDEBUG);

                                         (*CODE FILES USED IN GETCMD*)

      SYSFILE = (ASSMBLER,COMPILER,EDITOR,FILER,LINKER);

                                         (*ARCHIVAL INFO...THE DATE*)

      DATEREC = PACKED RECORD
                  MONTH: 0..12;          (*0 IMPLIES DATE NOT MEANINGFUL*)
                  DAY: 0..31;            (*DAY OF MONTH*)
                  YEAR: 0..100           (*100 IS TEMP DISK FLAG*)
                END (*DATEREC*) ;

                                         (*VOLUME TABLES*)
      UNITNUM = 0..MAXUNIT;
      VID = STRING[VIDLENG];

                                         (*DISK DIRECTORIES*)
      DIRRANGE = 0..MAXDIR;
      TID = STRING[TIDLENG];

      FILEKIND = (UNTYPEDFILE,XDSKFILE,CODEFILE,TEXTFILE,
                  INFOFILE,DATAFILE,GRAFFILE,FOTOFILE,SECUREDIR);

      DIRENTRY = RECORD
                   DFIRSTBLK: INTEGER;   (*FIRST PHYSICAL DISK ADDR*)
                   DLASTBLK: INTEGER;    (*POINTS AT BLOCK FOLLOWING*)
                   CASE DFKIND: FILEKIND OF
                     SECUREDIR,
                     UNTYPEDFILE: (*ONLY IN DIR[0]...VOLUME INFO*)
                        (DVID: VID;              (*NAME OF DISK VOLUME*)
                         DEOVBLK: INTEGER;       (*LASTBLK OF VOLUME*)
                         DNUMFILES: DIRRANGE;    (*NUM FILES IN DIR*)
                         DLOADTIME: INTEGER;     (*TIME OF LAST ACCESS*)
                         DLASTBOOT: DATEREC);    (*MOST RECENT DATE SETTING*)
                     XDSKFILE,CODEFILE,TEXTFILE,INFOFILE,
                     DATAFILE,GRAFFILE,FOTOFILE:
                        (DTID: TID;              (*TITLE OF FILE*)
                         DLASTBYTE: 1..FBLKSIZE; (*NUM BYTES IN LAST BLOCK*)
                         DACCESS: DATEREC)       (*LAST MODIFICATION DATE*)
                 END (*DIRENTRY*) ;

      DIRP = ^DIRECTORY;

      DIRECTORY = ARRAY [DIRRANGE] OF DIRENTRY;

                                         (*FILE INFORMATION*)

      CLOSETYPE = (CNORMAL,CLOCK,CPURGE,CCRUNCH);
      WINDOWP = ^WINDOW;
      WINDOW = PACKED ARRAY [0..0] OF CHAR;
      FIBP = ^FIB;

      FIB = RECORD
              FWINDOW: WINDOWP;  (*USER WINDOW...F^, USED BY GET-PUT*)
              FEOF,FEOLN: BOOLEAN;
              FSTATE: (FJANDW,FNEEDCHAR,FGOTCHAR);
              FRECSIZE: INTEGER; (*IN BYTES...0=>BLOCKFILE, 1=>CHARFILE*)
              CASE FISOPEN: BOOLEAN OF
                TRUE: (FISBLKD: BOOLEAN; (*FILE IS ON BLOCK DEVICE*)
                       FUNIT: UNITNUM;   (*PHYSICAL UNIT #*)
                       FVID: VID;        (*VOLUME NAME*)
                       FREPTCNT,         (* # TIMES F^ VALID W/O GET*)
                       FNXTBLK,          (*NEXT REL BLOCK TO IO*)
                       FMAXBLK: INTEGER; (*MAX REL BLOCK ACCESSED*)
                       FMODIFIED:BOOLEAN;(*PLEASE SET NEW DATE IN CLOSE*)
                       FHEADER: DIRENTRY;(*COPY OF DISK DIR ENTRY*)
                       CASE FSOFTBUF: BOOLEAN OF (*DISK GET-PUT STUFF*)
                         TRUE: (FNXTBYTE,FMAXBYTE: INTEGER;
                                FBUFCHNGD: BOOLEAN;
                                FBUFFER: PACKED ARRAY [0..FBLKSIZE] OF CHAR))
            END (*FIB*) ;

                                         (*USER WORKFILE STUFF*)

      INFOREC = RECORD
                  SYMFIBP,CODEFIBP: FIBP;        (*WORKFILES FOR SCRATCH*)
                  ERRSYM,ERRBLK,ERRNUM: INTEGER; (*ERROR STUFF IN EDIT*)
                  SLOWTERM,STUPID: BOOLEAN;      (*STUDENT PROGRAMMER ID!!*)
                  ALTMODE: CHAR;                 (*WASHOUT CHAR FOR COMPILER*)
                  GOTSYM,GOTCODE: BOOLEAN;       (*TITLES ARE MEANINGFUL*)
                  WORKVID,SYMVID,CODEVID: VID;   (*PERM&CUR WORKFILE VOLUMES*)
                  WORKTID,SYMTID,CODETID: TID    (*PERM&CUR WORKFILES TITLE*)
                END (*INFOREC*) ;

                                         (*CODE SEGMENT LAYOUTS*)

      SEGRANGE = 0..MAXSEG;
      SEGDESC = RECORD
                  DISKADDR: INTEGER;     (*REL BLK IN CODE...ABS IN SYSCOM^*)
                  CODELENG: INTEGER      (*# BYTES TO READ IN*)
                END (*SEGDESC*) ;

                                         (*DEBUGGER STUFF*)

      BYTERANGE = 0..255;
      TRICKARRAY = ARRAY [0..0] OF INTEGER; (* FOR MEMORY DIDDLING*)
      MSCWP = ^ MSCW;            (*MARK STACK RECORD POINTER*)
      MSCW = RECORD
               STATLINK: MSCWP;  (*POINTER TO PARENT MSCW*)
               DYNLINK: MSCWP;   (*POINTER TO CALLER'S MSCW*)
               MSSEG,MSJTAB: ^TRICKARRAY;
               MSIPC: INTEGER;
               LOCALDATA: TRICKARRAY
             END (*MSCW*) ;

                                         (*SYSTEM COMMUNICATION AREA*)
                                         (*SEE INTERPRETERS...NOTE  *)
                                         (*THAT WE ASSUME BACKWARD  *)
                                         (*FIELD ALLOCATION IS DONE *)

      SYSCOMREC = RECORD
                    IORSLT: IORSLTWD;    (*RESULT OF LAST IO CALL*)
                    XEQERR: INTEGER;     (*REASON FOR EXECERROR CALL*)
                    SYSUNIT: UNITNUM;    (*PHYSICAL UNIT OF BOOTLOAD*)
                    BUGSTATE: INTEGER;   (*DEBUGGER INFO*)
                    GDIRP: DIRP;         (*GLOBAL DIR POINTER,SEE VOLSEARCH*)
                    LASTMP,STKBASE,BOMBP: MSCWP;
                    MEMTOP,SEG,JTAB: INTEGER;
                    BOMBIPC: INTEGER;    (*WHERE XEQERR BLOWUP WAS*)
                    HLTLINE: INTEGER;    (*MORE DEBUGGER STUFF*)
                    BRKPTS: ARRAY [0..3] OF INTEGER;
                    RETRIES: INTEGER;    (*DRIVERS PUT RETRY COUNTS*)
                    EXPANSION: ARRAY [0..8] OF INTEGER;
                    HIGHTIME,LOWTIME: INTEGER;
                    MISCINFO: PACKED RECORD
                                NOBREAK,STUPID,SLOWTERM,
                                HASXYCRT,HASLCCRT,HAS8510A,HASCLOCK: BOOLEAN;
                                USERKIND:(NORMAL, AQUIZ, BOOKER, PQUIZ)
                              END;
                    CRTTYPE: INTEGER;
                    CRTCTRL: PACKED RECORD
                               RLF,NDFS,ERASEEOL,ERASEEOS,HOME,ESCAPE: CHAR;
                               BACKSPACE: CHAR;
                               FILLCOUNT: 0..255;
                               CLEARSCREEN, CLEARLINE: CHAR;
                               PREFIXED: PACKED ARRAY [0..8] OF BOOLEAN
                             END;
                    CRTINFO: PACKED RECORD
                               WIDTH,HEIGHT: INTEGER;
                               RIGHT,LEFT,DOWN,UP: CHAR;
                               BADCH,CHARDEL,STOP,BREAK,FLUSH,EOF: CHAR;
                               ALTMODE,LINEDEL: CHAR;
                               BACKSPACE,ETX,PREFIX: CHAR;
                               PREFIXED: PACKED ARRAY [0..13] OF BOOLEAN
                             END;
                    SEGTABLE: ARRAY [SEGRANGE] OF
                                RECORD
                                  CODEUNIT: UNITNUM;
                                  CODEDESC: SEGDESC
                                END
                  END (*SYSCOM*);

      MISCINFOREC = RECORD
                      MSYSCOM: SYSCOMREC
                    END;

 VAR
     SYSCOM: ^SYSCOMREC;                 (*MAGIC PARAM...SET UP IN BOOT*)
     GFILES: ARRAY [0..5] OF FIBP;       (*GLOBAL FILES, 0=INPUT, 1=OUTPUT*)
     USERINFO: INFOREC;                  (*WORK STUFF FOR COMPILER ETC*)
     EMPTYHEAP: ^INTEGER;                (*HEAP MARK FOR MEM MANAGING*)
     INPUTFIB,OUTPUTFIB,                 (*CONSOLE FILES...GFILES ARE COPIES*)
     SYSTERM,SWAPFIB: FIBP;              (*CONTROL AND SWAPSPACE FILES*)
     SYVID,DKVID: VID;                   (*SYSUNIT VOLID & DEFAULT VOLID*)
     THEDATE: DATEREC;                   (*TODAY...SET IN FILER OR SIGN ON*)
     DEBUGINFO: ^INTEGER;                (*DEBUGGERS GLOBAL INFO WHILE RUNIN*)
     STATE: CMDSTATE;                    (*FOR GETCOMMAND*)
     PL: STRING;                         (*PROMPTLINE STRING...SEE PROMPT*)
     IPOT: ARRAY [0..4] OF INTEGER;      (*INTEGER POWERS OF TEN*)
     FILLER: STRING[11];                 (*NULLS FOR CARRIAGE DELAY*)
     DIGITS: SET OF '0'..'9';
     UNITABLE: ARRAY [UNITNUM] OF (*0 NOT USED*)
                 RECORD
                   UVID: VID;    (*VOLUME ID FOR UNIT*)
                   CASE UISBLKD: BOOLEAN OF
                     TRUE: (UEOVBLK: INTEGER)
                 END (*UNITABLE*) ;
     FILENAME: ARRAY [SYSFILE] OF STRING[23];

 (*-------------------------------------------------------------------------*)
 (* SYSTEM PROCEDURE FORWARD DECLARATIONS *)
 (* THESE ARE ADDRESSED BY OBJECT CODE... *)
 (*  DO NOT MOVE WITHOUT CAREFUL THOUGHT  *)

 PROCEDURE EXECERROR;
   FORWARD;
 PROCEDURE FINIT(VAR F: FIB; WINDOW: WINDOWP; RECWORDS: INTEGER);
   FORWARD;
 PROCEDURE FRESET(VAR F: FIB);
   FORWARD;
 PROCEDURE FOPEN(VAR F: FIB; VAR FTITLE: STRING;
                 FOPENOLD: BOOLEAN; JUNK: FIBP);
   FORWARD;
 PROCEDURE FCLOSE(VAR F: FIB; FTYPE: CLOSETYPE);
   FORWARD;
 PROCEDURE FGET(VAR F: FIB);
   FORWARD;
 PROCEDURE FPUT(VAR F: FIB);
   FORWARD;
 PROCEDURE XSEEK;
   FORWARD;
 FUNCTION FEOF(VAR F: FIB): BOOLEAN;
   FORWARD;
 FUNCTION FEOLN(VAR F: FIB): BOOLEAN;
   FORWARD;
 PROCEDURE FREADINT(VAR F: FIB; VAR I: INTEGER);
   FORWARD;
 PROCEDURE FWRITEINT(VAR F: FIB; I,RLENG: INTEGER);
   FORWARD;
 PROCEDURE XREADREAL;
   FORWARD;
 PROCEDURE XWRITEREAL;
   FORWARD;
 PROCEDURE FREADCHAR(VAR F: FIB; VAR CH: CHAR);
   FORWARD;
 PROCEDURE FWRITECHAR(VAR F: FIB; CH: CHAR; RLENG: INTEGER);
   FORWARD;
 PROCEDURE FREADSTRING(VAR F: FIB; VAR S: STRING; SLENG: INTEGER);
   FORWARD;
 PROCEDURE FWRITESTRING(VAR F: FIB; VAR S: STRING; RLENG: INTEGER);
   FORWARD;
 PROCEDURE FWRITEBYTES(VAR F: FIB; VAR A: WINDOW; RLENG,ALENG: INTEGER);
   FORWARD;
 PROCEDURE FREADLN(VAR F: FIB);
   FORWARD;
 PROCEDURE FWRITELN(VAR F: FIB);
   FORWARD;
 PROCEDURE SCONCAT(VAR DEST,SRC: STRING; DESTLENG: INTEGER);
   FORWARD;
 PROCEDURE SINSERT(VAR SRC,DEST: STRING; DESTLENG,INSINX: INTEGER);
   FORWARD;
 PROCEDURE SCOPY(VAR SRC,DEST: STRING; SRCINX,COPYLENG: INTEGER);
   FORWARD;
 PROCEDURE SDELETE(VAR DEST: STRING; DELINX,DELLENG: INTEGER);
   FORWARD;
 FUNCTION SPOS(VAR TARGET,SRC: STRING): INTEGER;
   FORWARD;
 FUNCTION FBLOCKIO(VAR F: FIB; VAR A: WINDOW;
                   NBLOCKS,RBLOCK: INTEGER; DOREAD: BOOLEAN): INTEGER;
   FORWARD;
 PROCEDURE FGOTOXY(X,Y: INTEGER);
   FORWARD;

 (* NON FIXED FORWARD DECLARATIONS *)

 FUNCTION VOLSEARCH(VAR FVID: VID; LOOKHARD: BOOLEAN;
                    VAR FDIR: DIRP): UNITNUM;
   FORWARD;
 PROCEDURE WRITEDIR(FUNIT: UNITNUM; FDIR: DIRP);
   FORWARD;
 FUNCTION DIRSEARCH(VAR FTID: TID; FINDPERM: BOOLEAN; FDIR: DIRP): DIRRANGE;
   FORWARD;
 FUNCTION SCANTITLE(FTITLE: STRING; VAR FVID: VID; VAR FTID: TID;
                    VAR FSEGS: INTEGER; VAR FKIND: FILEKIND): BOOLEAN;
   FORWARD;
 PROCEDURE DELENTRY(FINX: DIRRANGE; FDIR: DIRP);
   FORWARD;
 PROCEDURE INSENTRY(VAR FENTRY: DIRENTRY; FINX: DIRRANGE; FDIR: DIRP);
   FORWARD;
 PROCEDURE HOMECURSOR;
   FORWARD;
 PROCEDURE CLEARSCREEN;
   FORWARD;
 PROCEDURE CLEARLINE;
   FORWARD;
 PROCEDURE PROMPT;
   FORWARD;
 FUNCTION SPACEWAIT(FLUSH: BOOLEAN): BOOLEAN;
   FORWARD;
 FUNCTION GETCHAR(FLUSH: BOOLEAN): CHAR;
   FORWARD;
 PROCEDURE COMMAND;
   FORWARD;
