(*$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);

					(*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;
				 EXPANSION: PACKED ARRAY [0..3] OF CHAR
			    END;
		   CRTINFO: PACKED RECORD
				 WIDTH,HEIGHT: INTEGER;
				 RIGHT,LEFT,DOWN,UP: CHAR;
				 BADCH,CHARDEL,STOP,BREAK,FLUSH,EOF: CHAR;
				 ALTMODE,LINEDEL: CHAR;
				 EXPANSION: PACKED ARRAY [0..5] OF CHAR
			    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*) ;

(*-------------------------------------------------------------------------*)
(* 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;
                                                                 