mirror of
https://github.com/PDP-10/its.git
synced 2026-01-27 12:42:10 +00:00
Files from CLIB; AR2 CLIB.
This commit is contained in:
35
src/c/code.insert
Normal file
35
src/c/code.insert
Normal file
@@ -0,0 +1,35 @@
|
||||
; MACROS FOR SEPARATE CODE LITERAL AREA
|
||||
; THIS DOES NOT HANDLE RECURSIVE CALLS
|
||||
|
||||
CD%N==0
|
||||
IF1,[CD%LOC==0]
|
||||
|
||||
DEFINE CD%AS *PREFIX*,#SEGNO,*SUFFIX*
|
||||
PREFIX!SEGNO!SUFFIX
|
||||
TERMIN
|
||||
|
||||
DEFINE CODE BODY
|
||||
IF2,[ CD%AS/CD%LOC+CD%/,CD%N+1]
|
||||
|
||||
CD%N==CD%N+1
|
||||
DOT==.-1
|
||||
CD%OLC==.
|
||||
IF1,[
|
||||
BODY
|
||||
CD%AS /CD%/,CD%N,/==CD%LOC/
|
||||
CD%LOC==CD%LOC+<.-CD%OLC>
|
||||
]
|
||||
IF2,[
|
||||
CD%AS /LOC CD%LOC+CD%/,CD%N
|
||||
BODY
|
||||
]
|
||||
LOC CD%OLC
|
||||
TERMIN
|
||||
|
||||
DEFINE INSCODE
|
||||
IF1,[
|
||||
CD%SIZ==CD%LOC
|
||||
CD%LOC==.
|
||||
BLOCK CD%SIZ
|
||||
]
|
||||
TERMIN
|
||||
163
src/c/nm.insert
Normal file
163
src/c/nm.insert
Normal file
@@ -0,0 +1,163 @@
|
||||
.INSRT C;CODE INSERT
|
||||
|
||||
.OFNM2=SIXBIT/STK/
|
||||
|
||||
CL=PUSHJ P,
|
||||
RTN=POPJ P,
|
||||
|
||||
.VCALL=2_33
|
||||
.ACALL=3_33
|
||||
.XCALL=4_33
|
||||
|
||||
DEFINE SYSCAL NAME,ARGS,DUMMY,LABEL
|
||||
SETZ A,
|
||||
.CALL [SETZ
|
||||
.1STWD SIXBIT /NAME/
|
||||
ARGS
|
||||
403000,,A
|
||||
]
|
||||
IFSN [LABEL][]GO LABEL
|
||||
IFSE [LABEL][]MOVN A,A
|
||||
TERMIN
|
||||
|
||||
DEFINE INFORM A,B
|
||||
IF1,[PRINTX \ A = B
|
||||
\]
|
||||
TERMIN
|
||||
|
||||
; SUPPORT ROUTINES
|
||||
|
||||
DEFINE %LEN [LIST]
|
||||
%COUNT==0
|
||||
IRP ELEM,,LIST
|
||||
%COUNT==%COUNT+1
|
||||
TERMIN
|
||||
TERMIN
|
||||
|
||||
DEFINE DEFVAR NAME,#OFFSET
|
||||
DEFINE NAME
|
||||
<OFFSET-%P>&262143.(P)TERMIN
|
||||
TERMIN
|
||||
|
||||
; DEFINE C-CALLABLE PROCEDURE (C NAME)
|
||||
|
||||
DEFINE CENTRY NAME,[ARGS],[VARS]
|
||||
PROLOG Z!NAME,NAME,ARGS,VARS
|
||||
TERMIN
|
||||
|
||||
; DEFINE C-CALLABLE PROCEDURE (MIDAS NAME)
|
||||
|
||||
DEFINE MENTRY NAME,[ARGS],[VARS]
|
||||
PROLOG NAME,NAME,ARGS,VARS
|
||||
TERMIN
|
||||
|
||||
; DEFINE MIDAS ENTRY POINT (NOT PROCEDURE)
|
||||
|
||||
DEFINE IENTRY NAME
|
||||
NAME": TERMIN
|
||||
|
||||
; PROLOG MACRO
|
||||
|
||||
DEFINE PROLOG MNAME,PNAME,[ARGS],[VARS]
|
||||
%LEN ARGS
|
||||
%A==%COUNT
|
||||
%LEN VARS
|
||||
%V==%COUNT
|
||||
%OFF== -<%A+%V>
|
||||
IRP ARGNAM,,ARGS
|
||||
DEFVAR ARGNAM,%OFF
|
||||
%OFF==%OFF+1
|
||||
TERMIN
|
||||
%OFF==%OFF+1
|
||||
IRP VARNAM,,VARS
|
||||
DEFVAR VARNAM,%OFF
|
||||
%OFF==%OFF+1
|
||||
TERMIN
|
||||
%A,,[ASCIZ/PNAME/]
|
||||
MNAME": IFN %V,[ADDI P,%V]
|
||||
TERMIN
|
||||
|
||||
; DEFINE SYNONYM FOR C-CALLABLE ENTRY POINT
|
||||
|
||||
DEFINE XENTRY NEWNAME,OLDNAME
|
||||
Z!NEWNAME"=Z!OLDNAME"
|
||||
TERMIN
|
||||
|
||||
; DEFINE MIDAS-ACCESSIBLE DATA
|
||||
|
||||
DEFINE MDATA NAME
|
||||
NAME":TERMIN
|
||||
|
||||
; FATAL ERROR
|
||||
|
||||
DEFINE CROAK STRING/
|
||||
.VALUE [ASCIZ \
|
||||
: STRING
|
||||
\]
|
||||
TERMIN
|
||||
|
||||
; RETURN STATEMENT
|
||||
|
||||
DEFINE RETURN
|
||||
IFE %A,[
|
||||
IFN %V,[SUBI P,%V]
|
||||
POPJ P,
|
||||
]
|
||||
IFN %A,[
|
||||
SUBI P,%V+%A+1
|
||||
JRST @<%A+1>(P)
|
||||
]
|
||||
TERMIN
|
||||
|
||||
; CALL STATEMENT
|
||||
|
||||
DEFINE CALL NAME,[ARGS]
|
||||
NN==0
|
||||
IRP ARG,,ARGS
|
||||
PPUSH ARG
|
||||
NN==NN+1
|
||||
TERMIN
|
||||
ICALL NN,NAME
|
||||
TERMIN
|
||||
|
||||
; MIDAS-CALL STATEMENT
|
||||
|
||||
DEFINE MCALL NAME,[ARGS]
|
||||
NN==0
|
||||
IRP ARG,,ARGS
|
||||
PPUSH ARG
|
||||
NN==NN+1
|
||||
TERMIN
|
||||
CCALL NN,NAME"
|
||||
TERMIN
|
||||
|
||||
; VARIABLE-CALL STATEMENT
|
||||
|
||||
DEFINE VCALL F,[ARGS]
|
||||
NN==0
|
||||
IRP ARG,,ARGS
|
||||
PPUSH ARG
|
||||
NN==NN+1
|
||||
TERMIN
|
||||
CCALL NN,F
|
||||
TERMIN
|
||||
|
||||
; INTERNAL CALL
|
||||
|
||||
DEFINE ICALL N,NAME
|
||||
CCALL N,Z!NAME"
|
||||
TERMIN
|
||||
|
||||
; HACK FOR CONSTANTS
|
||||
|
||||
EQUALS NM%EN END
|
||||
EXPUNGE END
|
||||
DEFINE END ENDLOC
|
||||
.CODE
|
||||
INSCODE
|
||||
.PDATA
|
||||
CONSTANTS
|
||||
NM%EN ENDLOC
|
||||
TERMIN
|
||||
|
||||
.CODE
|
||||
280
src/clib/ac.c
Normal file
280
src/clib/ac.c
Normal file
@@ -0,0 +1,280 @@
|
||||
#
|
||||
/*
|
||||
|
||||
AC - Array of Characters Cluster
|
||||
|
||||
operations:
|
||||
|
||||
ac_new () => ac create empty array
|
||||
ac_alloc (size) => ac create empty array, preferred size
|
||||
ac_create (string) => ac create with initial value
|
||||
ac_xh (ac, c) => c extend array with character
|
||||
ac_trim (ac) => ac trim excess storage
|
||||
ac_fetch (ac, i) => c fetch character from array
|
||||
ac_link (ac) => ac make new link to array
|
||||
ac_unlink (ac) remove link to array
|
||||
ac_puts (ac, f) print array
|
||||
ac_cat (ac, ac) => ac concatenate arrays
|
||||
ac_copy (ac) => ac copy array
|
||||
ac_string (ac) => *char return string version
|
||||
ac_size (ac) => size return current size of array
|
||||
ac_flush (ac) make array empty
|
||||
ac_n () => int return # of active arrays
|
||||
|
||||
*/
|
||||
|
||||
struct rep {
|
||||
int count; /* reference count */
|
||||
char *s; /* pointer to actual array */
|
||||
int csize; /* logical size of array */
|
||||
int msize; /* physical size of array (at least csize+1) */
|
||||
};
|
||||
|
||||
# define ac struct rep* /* watch usage! */
|
||||
# define ASIZE 4 /* number of words in rep */
|
||||
# define initial_size 8 /* default initial allocation */
|
||||
|
||||
char *calloc ();
|
||||
int *salloc ();
|
||||
ac ac_new();
|
||||
ac ac_alloc();
|
||||
ac ac_create();
|
||||
ac ac_link();
|
||||
ac ac_cat();
|
||||
ac ac_copy();
|
||||
|
||||
static int count;
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_NEW - Create empty array.
|
||||
AC_ALLOC - Create empty array, preferred size given.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
ac ac_new ()
|
||||
|
||||
{return (ac_alloc (initial_size));}
|
||||
|
||||
ac ac_alloc (sz)
|
||||
|
||||
{ac a;
|
||||
|
||||
if (sz<0) sz=0;
|
||||
a = salloc (ASIZE);
|
||||
a->count = 1;
|
||||
a->csize = 0;
|
||||
a->msize = sz+1;
|
||||
a->s = calloc (a->msize);
|
||||
++count;
|
||||
return (a);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_CREATE - Create array with initial value.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
ac ac_create (s) char s[];
|
||||
|
||||
{register char *p;
|
||||
register int sz;
|
||||
register ac a;
|
||||
|
||||
sz = slen (s);
|
||||
a = ac_alloc (sz);
|
||||
a->csize = sz;
|
||||
p = a->s;
|
||||
while (--sz >= 0) *p++ = *s++;
|
||||
return (a);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_XH - Extend Array with Character.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
char ac_xh (a, c) register ac a;
|
||||
|
||||
{register char *p, *q;
|
||||
char *old;
|
||||
int i;
|
||||
|
||||
if ((i = a->csize) >= a->msize-1)
|
||||
{old = p = a->s;
|
||||
a->s = q = calloc (a->msize =* 2);
|
||||
while (--i >= 0) *q++ = *p++;
|
||||
if (old) cfree (old);
|
||||
}
|
||||
a->s[a->csize++] = c;
|
||||
return (c);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_TRIM - Discard excess storage.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
ac ac_trim (a) register ac a;
|
||||
|
||||
{register char *p, *q;
|
||||
char *old;
|
||||
int i;
|
||||
|
||||
if ((i = a->csize) < a->msize-1)
|
||||
{old = p = a->s;
|
||||
a->s = q = calloc (a->msize = a->csize + 1);
|
||||
while (--i >= 0) *q++ = *p++;
|
||||
if (old) cfree (old);
|
||||
}
|
||||
return (a);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_FETCH - Fetch Character from Array.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
char ac_fetch (a, n) ac a;
|
||||
|
||||
{extern int cerr;
|
||||
if (n<0 || n>=a->csize)
|
||||
{cprint (cerr, "Character array bounds error.");
|
||||
return (0);
|
||||
}
|
||||
return (a->s[n]);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_LINK - Create link to array.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
ac ac_link (a) ac a;
|
||||
|
||||
{++a->count;
|
||||
return (a);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_UNLINK - Remove link to array.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
ac_unlink (a) ac a;
|
||||
|
||||
{if (--a->count == 0)
|
||||
{if (a->s) cfree (a->s);
|
||||
--count;
|
||||
sfree (a);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_PUTS - Print array.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
ac_puts (a, f, wid) ac a; /* 3 args for cprint usage */
|
||||
|
||||
{register char *p;
|
||||
register int i;
|
||||
|
||||
p = a->s;
|
||||
i = a->csize;
|
||||
while (--i >= 0) cputc (*p++, f);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_CAT - Concatenate arrays.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
ac ac_cat (a1, a2) ac a1; ac a2;
|
||||
|
||||
{register ac a;
|
||||
register char *p, *q;
|
||||
int i;
|
||||
|
||||
a = ac_alloc (i = a1->csize + a2->csize);
|
||||
a->csize = i;
|
||||
p = a->s;
|
||||
q = a1->s;
|
||||
i = a1->csize;
|
||||
while (--i>=0) *p++ = *q++;
|
||||
q = a2->s;
|
||||
i = a2->csize;
|
||||
while (--i>=0) *p++ = *q++;
|
||||
return (a);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_COPY - Copy array.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
ac ac_copy (a1) ac a1;
|
||||
|
||||
{register ac a;
|
||||
register char *p, *q;
|
||||
int i;
|
||||
|
||||
a = ac_alloc (i = a1->csize);
|
||||
a->csize = i;
|
||||
p = a->s;
|
||||
q = a1->s;
|
||||
while (--i >= 0) *p++ = *q++;
|
||||
return (a);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_STRING - Return string version of array. The returned
|
||||
string is valid only while the array remains linked
|
||||
to and unchanged.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
char *ac_string (a) ac a;
|
||||
|
||||
{a->s[a->csize]=0;
|
||||
return (a->s);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_SIZE - Return current size of array.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int ac_size (a) ac a;
|
||||
|
||||
{return (a->csize);}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_FLUSH - Make array empty
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
ac_flush (a) ac a;
|
||||
|
||||
{a->csize = 0;}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
AC_N - Return number of active arrays.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int ac_n () {return (count);}
|
||||
|
||||
224
src/clib/alloc.cmid
Normal file
224
src/clib/alloc.cmid
Normal file
@@ -0,0 +1,224 @@
|
||||
;
|
||||
; ALLOC - C FREE STORAGE ROUTINES
|
||||
;
|
||||
; This file is PDP-10 dependent, system independent.
|
||||
;
|
||||
; CALLOC (SIZE) => *CHAR ; ALLOCATE ZEROED CHARACTERS
|
||||
; SALLOC (SIZE) => *INT ; ALLOCATE ZEROED WORDS
|
||||
; CFREE (*CHAR) ; RETURN CHARACTERS
|
||||
; SFREE (*INT) ; RETURN WORDS
|
||||
;
|
||||
; AFREE (SIZE) => (ADDR) ; ALLOCATE GARBAGE WORDS
|
||||
; AFRET (ADDR, SIZE) ; DEALLOCATE WORDS
|
||||
; AFREZ (SIZE) => (ADDR) ; ALLOCATE AND ZERO WORDS
|
||||
;
|
||||
; ALOCSTAT (&NWALLOC, &NBFREE) => NWFREE ; COMPUTE STATS
|
||||
;
|
||||
|
||||
TITLE ALLOC
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
|
||||
; THESE ARE STORAGE-ALLOCATION ROUTINES WITH SOME PROTECTION
|
||||
|
||||
CENTRY CALLOC,[NWORDS] ; ALLOCATE CHARACTERS
|
||||
XENTRY SALLOC,CALLOC ; ALLOCATE WORDS
|
||||
|
||||
SKIPL A,NWORDS ; DON'T ADD TO BAD SIZE
|
||||
ADDI A,2 ; FOR HEADER WORDS
|
||||
CALL AFREZ,[A]
|
||||
ADDI A,2 ; POINTER TO USER AREA OF BLOCK
|
||||
MOVE B,NWORDS
|
||||
MOVEM B,-1(A) ; STORE SIZE IN HEADER
|
||||
MOVE B,A
|
||||
ADD B,[147506732514]
|
||||
MOVEM B,-2(A) ; MAGIC WORD IN HEADER
|
||||
RETURN
|
||||
|
||||
CENTRY CFREE,[PTR] ; RETURN CHARACTERS
|
||||
XENTRY SFREE,CFREE ; RETURN WORDS
|
||||
|
||||
MOVE A,PTR
|
||||
MOVE B,-2(A)
|
||||
SUB B,A
|
||||
CAME B,[147506732514]
|
||||
GO CF$BAD
|
||||
MOVEI A,-2(A)
|
||||
MOVE B,1(A)
|
||||
ADDI B,2
|
||||
CALL AFRET,[A,B]
|
||||
SETZ A,
|
||||
CF$RET: RETURN
|
||||
CF$BAD: CROAK BAD CALL TO CFREE/SFREE
|
||||
SETO A,
|
||||
GO CF$RET
|
||||
|
||||
|
||||
.IDATA
|
||||
MDATA FNWORDS ; NUMBER OF WORDS ALLOCATED
|
||||
0
|
||||
MDATA FLIST
|
||||
FLIST+1 ; LIST OF FREE BLOCKS
|
||||
0
|
||||
.CODE
|
||||
;
|
||||
; AFREE - ALLOCATE STORAGE
|
||||
;
|
||||
|
||||
CENTRY AFREE,[BSIZE]
|
||||
XENTRY GETVEC,AFREE
|
||||
|
||||
MOVE A,BSIZE
|
||||
JUMPLE A,AE$BAD ; SIZE MUST BE POSITIVE
|
||||
CAIL A,400000 ; SIZE MUST BE REASONABLE
|
||||
GO AE$BAD
|
||||
HRLZI D,(A) ; SIZE IN LEFT HALF FOR COMPARISON
|
||||
MOVEI B,FLIST ; PREVIOUS BLOCK ADDR IN B
|
||||
HRRZ C,(B) ; CURRENT BLOCK ADDR IN C
|
||||
A1: CAMG D,(C) ; IS CURRENT BLOCK BIG ENOUGH?
|
||||
GO A3 ; YES
|
||||
MOVEI B,(C) ; CURRENT BLOCK -> PREVIOUS BLOCK
|
||||
HRRZ C,(C) ; NEXT BLOCK -> CURRENT BLOCK
|
||||
JUMPN C,A1 ; BLOCK EXISTS => LOOP
|
||||
HLRZ B,D ; DESIRED SIZE IN B
|
||||
PPUSH B ; SAVE SIZE NEEDED
|
||||
CALL GETCORE,[B] ; ALLOCATE NEW BLOCK (SIZE,,ADDR)
|
||||
HLRZ B,A ; SIZE OBTAINED
|
||||
HRRZ A,A ; ADDRESS OF BLOCK
|
||||
PPOP D ; SIZE NEEDED
|
||||
SUBI B,(D) ; HOW MUCH EXTRA OBTAINED?
|
||||
JUMPE B,AE$RET ; NO EXCESS => DONE
|
||||
PPUSH A ; ADDRESS OF BLOCK
|
||||
ADDM B,(P) ; ADDRESS OF DESIRED PART OF BLOCK
|
||||
CALL AFRET,[A,B] ; RETURN THE EXCESS
|
||||
PPOP A ; ADDRESS OF DESIRED PART OF BLOCK
|
||||
GO AE$RET ; DONE
|
||||
|
||||
; HERE WHEN A SUFFICIENTLY LARGE BLOCK FOUND IN LIST
|
||||
|
||||
A3: HLRZ D,D ; DESIRED SIZE IN D
|
||||
HLRZ A,(C) ; SIZE OF BLOCK IN LIST
|
||||
SUBI A,(D) ; EXCESS
|
||||
JUMPE A,A4 ; NO EXCESS => DELETE BLOCK FROM LIST
|
||||
HRLM A,(C) ; NEW BLOCK SIZE
|
||||
ADDI A,(C) ; ADDRESS OF DESIRED PART OF BLOCK
|
||||
GO AE$RET ; DONE
|
||||
|
||||
; HERE WHEN ENTIRE BLOCK IS TO BE REMOVED FROM THE LIST
|
||||
|
||||
A4: HRRZ A,(C) ; NEXT BLOCK IN LIST
|
||||
HRRM A,(B) ; CHAIN TO PREVIOUS BLOCK
|
||||
MOVEI A,(C) ; RETURN THIS BLOCK
|
||||
GO AE$RET ; DONE
|
||||
|
||||
AE$BAD: CROAK AFREE CALLED WITH BAD SIZE ARGUMENT
|
||||
SETZ A,
|
||||
AE$RET: RETURN ; DONE
|
||||
|
||||
;
|
||||
; AFRET - DEALLOCATE STORAGE
|
||||
;
|
||||
|
||||
CENTRY AFRET,[PTR,BSIZE]
|
||||
|
||||
MOVE A,PTR
|
||||
MOVE B,BSIZE
|
||||
JUMPLE B,CODE [ ; SIZE MUST BE POSITIVE
|
||||
CROAK AFRET CALLED WITH BAD SIZE ARGUMENT
|
||||
GO ARRET
|
||||
]
|
||||
MOVEI C,FLIST ; ADDRESS OF PREVIOUS BLOCK IN C
|
||||
HRRZ D,(C) ; ADDRESS OF CURRENT BLOCK IN D
|
||||
A5: CAIG A,(D) ; FIND PLACE IN LIST
|
||||
GO A8 ; NEW BLOCK GOES HERE
|
||||
MOVEI C,(D) ; CURRENT BLOCK -> PREVIOUS BLOCK
|
||||
HRRZ D,(D) ; NEXT BLOCK -> CURRENT BLOCK
|
||||
JUMPN D,A5 ; BLOCK EXISTS => LOOP
|
||||
|
||||
; HERE TO INSERT NEW BLOCK AFTER A GIVEN BLOCK IN LIST
|
||||
|
||||
A6: HLRZ D,(C) ; SIZE OF OLD BLOCK
|
||||
ADDI D,(C) ; END OF OLD BLOCK
|
||||
CAIGE A,(D) ; OVERLAP WITH PREVIOUS BLOCK ?
|
||||
GO CODE [ ; YES, ERROR
|
||||
CROAK AFRET CALLED WITH BAD ADDRESS
|
||||
GO ARRET
|
||||
]
|
||||
CAIN A,(D) ; CONTIGUOUS WITH PREVIOUS BLOCK ?
|
||||
GO A7 ; YES, GO MERGE THEM
|
||||
HRRZ D,(C) ; ADDRESS OF NEXT BLOCK (IF ANY)
|
||||
HRLI D,(B) ; SIZE OF BLOCK BEING FREED (IN LEFT HALF)
|
||||
MOVEM D,(A) ; MAKE DOPE WORD OF BLOCK BEING FREED
|
||||
HRRM A,(C) ; CHAIN IT TO PREVIOUS BLOCK
|
||||
GO ARRET ; DONE
|
||||
|
||||
; HERE TO MERGE BLOCK WITH PREVIOUS BLOCK (ADDR IN C)
|
||||
|
||||
A7: HLRZ D,(C) ; SIZE OF OLD BLOCK
|
||||
ADDI D,(B) ; ADD SIZE OF BLOCK BEING FREED
|
||||
HRLM D,(C) ; STORE NEW SIZE IN OLD BLOCK
|
||||
GO ARRET ; DONE
|
||||
|
||||
; HERE IN INSERT NEW BLOCK IN MIDDLE OF LIST
|
||||
|
||||
A8: MOVEI 0,(A) ; ADDRESS OF NEW BLOCK
|
||||
ADDI 0,(B) ; END OF NEW BLOCK
|
||||
CAILE 0,(D) ; OVERLAP WITH NEXT BLOCK ?
|
||||
GO CODE [ ; YES, ERROR
|
||||
CROAK AFRET CALLED WITH BAD ADDRESS
|
||||
GO ARRET
|
||||
]
|
||||
CAIE 0,(D) ; CONTIGUOUS WITH NEXT BLOCK ?
|
||||
GO A6 ; NO, APPEND TO PREVIOUS BLOCK
|
||||
MOVS 0,(D) ; SWAPPED DOPE WORD OF NEXT BLOCK
|
||||
ADDI 0,(B) ; SIZE OF COMBINED BLOCK
|
||||
MOVSM 0,(A) ; MAKE DOPE WORD OF COMBINED BLOCK
|
||||
HRRM A,(C) ; CHAIN IT TO PREVIOUS BLOCK
|
||||
HLRZ D,(C) ; SIZE OF PREVIOUS BLOCK
|
||||
ADDI D,(C) ; END OF PREVIOUS BLOCK
|
||||
CAIE D,(A) ; CONTIGUOUS WITH PREVIOUS BLOCK ALSO ?
|
||||
GO ARRET ; NO, DONE
|
||||
HLRZ D,(C) ; SIZE OF PREVIOUS BLOCK
|
||||
ADDI 0,(D) ; SIZE OF COMBINED BLOCK
|
||||
MOVSM 0,(C) ; MERGE AGAIN
|
||||
ARRET: RETURN ; DONE
|
||||
|
||||
|
||||
;
|
||||
; AFREZ - ALLOCATE ZEROED BLOCK
|
||||
;
|
||||
|
||||
CENTRY AFREZ,[BSIZE]
|
||||
|
||||
CALL AFREE,[BSIZE] ; ALLOCATE A BLOCK
|
||||
SETZM (A) ; ZERO FIRST WORD
|
||||
MOVE B,BSIZE ; THE SIZE
|
||||
SOJE B,AZRET ; NUMBER OF WORDS REMAINING TO BE ZEROED
|
||||
ADDI B,(A) ; LAST WORD OF BLOCK
|
||||
HRLZI C,(A) ; FIRST WORD OF BLOCK (LEFT HALF)
|
||||
HRRI C,1(A) ; SECOND WORD OF BLOCK (RIGHT HALF)
|
||||
BLT C,(B) ; TRANSFER ZEROES
|
||||
AZRET: RETURN ; DONE
|
||||
|
||||
;
|
||||
; ALOCSTAT - COMPUTE ALLOCATION STATISTICS
|
||||
;
|
||||
|
||||
CENTRY ALOCSTAT,[PNALOC,PNBFREE]
|
||||
|
||||
MOVE A,FNWORDS ; NUMBER ALLOCATED
|
||||
MOVEM A,@PNALOC
|
||||
SETZ A, ; ZERO SUM OF FREE BLOCK SIZES
|
||||
SETZM @PNBFREE ; ZERO COUNT OF FREE BLOCKS
|
||||
MOVEI B,FLIST ; PREVIOUS BLOCK ADDR IN B
|
||||
HRRZ C,(B) ; CURRENT BLOCK ADDR IN C
|
||||
A9: HLRZ D,(C) ; GET SIZE OF BLOCK
|
||||
ADD A,D ; ADD TO SUM
|
||||
AOS @PNBFREE
|
||||
MOVEI B,(C) ; CURRENT BLOCK -> PREVIOUS BLOCK
|
||||
HRRZ C,(C) ; NEXT BLOCK -> CURRENT BLOCK
|
||||
JUMPN C,A9 ; BLOCK EXISTS => LOOP
|
||||
RETURN
|
||||
|
||||
END
|
||||
25
src/clib/apfnam.c
Normal file
25
src/clib/apfnam.c
Normal file
@@ -0,0 +1,25 @@
|
||||
/**********************************************************************
|
||||
|
||||
APFNAME - Append suffix to file name
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
char *apfname (dest, source, suffix)
|
||||
char *dest, *source, *suffix;
|
||||
|
||||
{fnsfd (dest, source, 0, 0, 0, suffix, "", "");
|
||||
return (dest);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
FNMKOUT - Make output file name
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
char *fnmkout (dest, source, suffix)
|
||||
char *dest, *source, *suffix;
|
||||
|
||||
{fnsfd (dest, source, "", 0, 0, suffix, "", "");
|
||||
return (dest);
|
||||
}
|
||||
Binary file not shown.
16
src/clib/atoi.c
Normal file
16
src/clib/atoi.c
Normal file
@@ -0,0 +1,16 @@
|
||||
/**********************************************************************
|
||||
|
||||
ATOI - Convert string to Integer
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int atoi (s) char s[];
|
||||
|
||||
{int i, f, c;
|
||||
|
||||
if (!s) return (0);
|
||||
i = f = 0;
|
||||
if (*s == '-') {++s; ++f;}
|
||||
while ((c = *s++)>='0' && c<='9') i = i*10 + c-'0';
|
||||
return (f?-i:i);
|
||||
}
|
||||
20
src/clib/blt.cmid
Normal file
20
src/clib/blt.cmid
Normal file
@@ -0,0 +1,20 @@
|
||||
;
|
||||
; BLT
|
||||
;
|
||||
; This file is PDP-10 dependent, system-independent.
|
||||
;
|
||||
|
||||
TITLE BLT
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
CENTRY BLT,[FROM,TO,NUM]
|
||||
|
||||
HRRZ A,TO
|
||||
HRRZI B,-1(A)
|
||||
ADD B,NUM
|
||||
HRL A,FROM
|
||||
BLT A,(B)
|
||||
RETURN
|
||||
|
||||
END
|
||||
56
src/clib/c10boo.cmid
Normal file
56
src/clib/c10boo.cmid
Normal file
@@ -0,0 +1,56 @@
|
||||
;
|
||||
; C10BOO - Bootstrapper Routine
|
||||
;
|
||||
; This file is ITS dependent.
|
||||
;
|
||||
TITLE BOOTSTRAP
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
LSTART==6 ; WHERE BOOTSTRAP LOADER WILL BE MOVED TO
|
||||
LCHN==15 ; LOAD FILE CHANNEL
|
||||
TCHN==16 ; TTY CHANNEL
|
||||
|
||||
CENTRY BOOTSTRAP,[FS]
|
||||
|
||||
MOVE C,FS
|
||||
SYSCAL OPEN,[MOVSI 6?MOVEI LCHN?(C)?1(C)?2(C)?3(C)],LOSE
|
||||
.SUSET [.ROPTI,,A] ; READ OPTION WORD
|
||||
TLZ A,OPTOPC+OPTINT ; TURN OFF OLD PC ON MPV, IOC AND
|
||||
; USE NEW INTERRUPT STACKING SCHEME
|
||||
.SUSET [.SOPTI,,A] ; SET OPTION WORD
|
||||
SETZM 42 ; DISABLE INTERRUPT HANDLING
|
||||
SETZ A,
|
||||
.SUSET [.SMASK,,A]
|
||||
SETZM 41
|
||||
|
||||
.OPEN TCHN,[SIXBIT/ TTY/]
|
||||
GO NOTTY
|
||||
.CALL [SETZ ; TURN OFF ECHOING
|
||||
'TTYSET
|
||||
1000,,TCHN
|
||||
[232222222222]
|
||||
SETZ [230222220222]
|
||||
]
|
||||
JFCL
|
||||
|
||||
NOTTY: MOVE 0,[LOADER,,LSTART]
|
||||
BLT 0,LSTART+LODLEN ; MOVE LOADER
|
||||
JRST LSTART ; EXECUTE LOADER
|
||||
LOSE: SETO A,
|
||||
RETURN
|
||||
|
||||
;
|
||||
; THE LOADING PROGRAM
|
||||
;
|
||||
|
||||
LOADER:
|
||||
.CALL [SETZ ? SIXBIT/LOAD/ ? MOVEI -1 ? SETZI LCHN]
|
||||
.VALUE
|
||||
.IOT LCHN,LSTART+5 ; READ STARTING ADDRESS
|
||||
.CLOSE LCHN,
|
||||
JRST @0 ; START PROGRAM
|
||||
-1,,0 ; IOT POINTER
|
||||
LODLEN==.-LOADER
|
||||
|
||||
END
|
||||
54
src/clib/c10cor.cmid
Normal file
54
src/clib/c10cor.cmid
Normal file
@@ -0,0 +1,54 @@
|
||||
;
|
||||
; C10COR - Basic Storage Allocation
|
||||
;
|
||||
; This file is ITS dependent.
|
||||
;
|
||||
|
||||
TITLE CCORE
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
.GLOBAL FNWORD
|
||||
|
||||
;
|
||||
; GETCORE - BASIC CORE ALLOCATOR
|
||||
;
|
||||
; GETCORE (SIZE) => SIZE,,ADDR
|
||||
;
|
||||
|
||||
CENTRY GETCORE,[BSIZE],[NPAGES,PTR]
|
||||
|
||||
MOVE B,BSIZE
|
||||
ADDI B,1777
|
||||
LSH B,-10. ; NUMBER OF PAGES NEEDED
|
||||
MOVEM B,NPAGES
|
||||
CALL PGJGET,[NPAGES] ; GET PAGES
|
||||
MOVN B,NPAGES ; MINUS NUMBER OF PAGES
|
||||
JUMPLE A,CODE [
|
||||
CROAK STORAGE EXHAUSTED
|
||||
GO DOT
|
||||
]
|
||||
MOVEM A,PTR
|
||||
HRL A,B ; AOBJN POINTER TO NEW PAGES
|
||||
TRYAGN: .CALL [SETZ
|
||||
'CORBLK
|
||||
1000,,300000 ; WANT READ AND WRITE ACCESS
|
||||
1000,,-1 ; PUT PAGE IN MY MAP
|
||||
A ; WHERE TO PUT THEM
|
||||
401000,,400001 ; GET FRESH PAGES
|
||||
]
|
||||
GO CODE [
|
||||
CROAK UNABLE TO GET CORE
|
||||
MOVEI 0,30.
|
||||
.SLEEP 0,
|
||||
GO TRYAGN
|
||||
]
|
||||
MOVE A,PTR
|
||||
LSH A,10. ; POINTER TO FIRST PAGE
|
||||
MOVE B,NPAGES
|
||||
LSH B,10. ; NUMBER OF WORDS GOTTEN
|
||||
ADDM B,FNWORDS ; SAVE FOR STATS
|
||||
HRL A,B ; SIZE,,ADDR
|
||||
RETURN
|
||||
|
||||
END
|
||||
119
src/clib/c10exc.c
Normal file
119
src/clib/c10exc.c
Normal file
@@ -0,0 +1,119 @@
|
||||
# include "clib/c.defs"
|
||||
|
||||
int exctime 0;
|
||||
int exccode 0;
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
EXECS - Execute a program with a given command string
|
||||
|
||||
Returns:
|
||||
|
||||
-5 Job valretted something and was not continued.
|
||||
-4 Internal fatal error.
|
||||
-3 Unable to load program file.
|
||||
-2 Unable to create job.
|
||||
-1 Unable to open program file.
|
||||
0 Job terminated normally.
|
||||
other Job terminated abnormally with said PIRQ
|
||||
|
||||
Sets:
|
||||
|
||||
exctime - job's CPU time in 1/60 sec. units
|
||||
exccode - contents of job's loc 1 at termination
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int execs (pname, args) char *pname, *args;
|
||||
|
||||
{int i, j, ich;
|
||||
char *s, buf[40];
|
||||
filespec f;
|
||||
|
||||
j = j_fload (pname);
|
||||
if (j<0) return (j);
|
||||
|
||||
j_sjcl (j, args);
|
||||
j_give_tty (j);
|
||||
j_start (j);
|
||||
|
||||
while (TRUE)
|
||||
{i = j_wait (j);
|
||||
j_take_tty (j);
|
||||
switch (i) {
|
||||
|
||||
case -1: return (-4);
|
||||
case -2: i = 0;
|
||||
break;
|
||||
case -3: s = j_valret (j);
|
||||
if (s)
|
||||
{cprint ("Job valrets: ");
|
||||
puts (s);
|
||||
}
|
||||
else
|
||||
{puts ("Job .VALUE 0");
|
||||
}
|
||||
cprint ("continue? ");
|
||||
gets (buf);
|
||||
if (buf[0]=='y' || buf[0]=='Y')
|
||||
{j_give_tty (j);
|
||||
j_start (j);
|
||||
continue;
|
||||
}
|
||||
i = -5;
|
||||
break;
|
||||
case -5: wsuset (014, 02); /* simulate ^Z typed */
|
||||
sleep (15);
|
||||
j_give_tty (j);
|
||||
j_start (j);
|
||||
continue;
|
||||
default: cprint ("Unhandled interrupt, continue? ");
|
||||
gets (buf);
|
||||
if (buf[0]=='y' || buf[0]=='Y')
|
||||
{j_give_tty (j);
|
||||
j_start (j);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
exctime = ruset (j_ch(j), 024) / (16666000./4069.);
|
||||
exccode = 0;
|
||||
if (!j_name (j, &f) && (ich=open(&f,4))>=0)
|
||||
{uiiot (ich);
|
||||
exccode = uiiot (ich);
|
||||
close (ich);
|
||||
}
|
||||
j_kill (j);
|
||||
return (i);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
EXECV - Execute file given a vector of arguments
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int execv (prog, argc, argv)
|
||||
char *prog, *argv[];
|
||||
|
||||
{char **ap, **ep, buff[300], *p, *s;
|
||||
int c;
|
||||
|
||||
p = buff;
|
||||
ap = argv;
|
||||
ep = argv + argc - 1;
|
||||
|
||||
while (ap <= ep)
|
||||
{s = *ap++;
|
||||
*p++ = '"';
|
||||
while (c = *s++) *p++ = c;
|
||||
*p++ = '"';
|
||||
*p++ = ' ';
|
||||
}
|
||||
|
||||
*p++ = 0;
|
||||
return (execs (prog, buff));
|
||||
}
|
||||
50
src/clib/c10exp.c
Normal file
50
src/clib/c10exp.c
Normal file
@@ -0,0 +1,50 @@
|
||||
# include "c/c.defs"
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
EXPAND ARGUMENT VECTOR CONTAINING FILE NAME PATTERNS
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
static char **next;
|
||||
static char *bufp;
|
||||
|
||||
int exparg (argc, argv, outv, buffer)
|
||||
char *argv[], *outv[], buffer[];
|
||||
|
||||
{int i, expfs();
|
||||
char *s;
|
||||
|
||||
bufp = buffer;
|
||||
next = outv;
|
||||
i = 0;
|
||||
while (i<argc)
|
||||
{s = argv[i++];
|
||||
if (expmagic (s)) mapdir (s, expfs);
|
||||
else *next++ = s;
|
||||
}
|
||||
return (next-outv);
|
||||
}
|
||||
|
||||
int expmagic (s) /* does it contain magic pattern chars? */
|
||||
char *s;
|
||||
|
||||
{int c, flag;
|
||||
flag = FALSE;
|
||||
while (c = *s++) switch (c) {
|
||||
case '?':
|
||||
case '*': flag = TRUE; continue;
|
||||
case '/': flag = FALSE; continue;
|
||||
case '\\': if (*s) ++s; continue;
|
||||
}
|
||||
return (flag);
|
||||
}
|
||||
|
||||
expfs (fs)
|
||||
filespec *fs;
|
||||
|
||||
{char *prfile (), *p;
|
||||
p = bufp;
|
||||
bufp = (prfile (fs, bufp)) + 1;
|
||||
*next++ = p;
|
||||
}
|
||||
230
src/clib/c10fd.c
Normal file
230
src/clib/c10fd.c
Normal file
@@ -0,0 +1,230 @@
|
||||
# include "c.defs"
|
||||
# include "its.bits"
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
FD-ITS
|
||||
File Directory Routines
|
||||
ITS Version
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
FDMAP (P, F)
|
||||
|
||||
Call F(S) for all filenames S that match the pattern P.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
static int (*fff)();
|
||||
|
||||
fdmap (p, f)
|
||||
char *p;
|
||||
int (*f)();
|
||||
|
||||
{extern int fdzzzz();
|
||||
fff = f;
|
||||
mapdirec (p, fdzzzz);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
The following routines are internal and probably should
|
||||
not be used by other programs.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
fdzzzz (fp)
|
||||
filespec *fp;
|
||||
|
||||
{char fn[100];
|
||||
prfile (fp, fn);
|
||||
(*fff)(fn);
|
||||
}
|
||||
|
||||
# define DIRSIZ 02000
|
||||
# define ENTSIZ 5
|
||||
|
||||
/* some useful SIXBIT numbers */
|
||||
|
||||
# define _FILE_ 0164651544516 /* .FILE. */
|
||||
# define _PDIRP_ 0104451621100 /* (DIR) */
|
||||
# define _DSK_ 0446353000000
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
MAPDIREC - Perform a function for each file in a
|
||||
directory whose name matches a given pattern
|
||||
(locked files not included)
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
mapdirec (pattern, f)
|
||||
char *pattern; /* the file name pattern */
|
||||
int (*f)(); /* the function */
|
||||
|
||||
{filespec ff;
|
||||
fparse (pattern, &ff);
|
||||
return (mapdfs (&ff, f));
|
||||
}
|
||||
|
||||
mapdfs (fp, f)
|
||||
filespec *fp; /* the parsed pattern */
|
||||
int (*f)(); /* the function */
|
||||
|
||||
{int n, v[2*DIRSIZ/ENTSIZ], *p, *q;
|
||||
char pat1[10], pat2[10], buf[10];
|
||||
filespec fs;
|
||||
|
||||
fs.dev = fp->dev;
|
||||
fs.dir = fp->dir;
|
||||
fs.fn1 = fp->fn1;
|
||||
fs.fn2 = fp->fn2;
|
||||
n = rddir (fp, v, 04);
|
||||
if (fp->fn1) c6tos (fp->fn1, pat1);
|
||||
if (fp->fn2) c6tos (fp->fn2, pat2);
|
||||
q = v + 2*n;
|
||||
for (p=v; p<q; p=+2)
|
||||
{if (fp->fn1)
|
||||
{c6tos (p[0], buf);
|
||||
if (!smatch (pat1, buf)) continue;
|
||||
}
|
||||
if (fp->fn2)
|
||||
{c6tos(p[1], buf);
|
||||
if (!smatch (pat2, buf)) continue;
|
||||
}
|
||||
fs.fn1 = p[0];
|
||||
fs.fn2 = p[1];
|
||||
(*f)(&fs);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
RDIREC - Read A Directory
|
||||
|
||||
S is a string specifying a directory.
|
||||
V will be filled with pairs of SIXBIT names, one for each file.
|
||||
The number of files is returned.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int rdirec (s, v, fs)
|
||||
char *s;
|
||||
int v[];
|
||||
filespec *fs;
|
||||
|
||||
{fparse (s, fs);
|
||||
if (!fs->dir) fs->dir = fs->fn1;
|
||||
return (rddir (fs, v, 0));
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
RDDIR - Read Directory
|
||||
|
||||
Return in V a list of names in the directory specified by FS.
|
||||
OPT is used to filter out some files:
|
||||
|
||||
if (opt & 01) no-links
|
||||
if (opt & 02) no-backed-up-files
|
||||
if (opt & 04) no-locked-files
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int rddir (fp, v, opt)
|
||||
filespec *fp;
|
||||
int v[], opt;
|
||||
|
||||
{int buf[DIRSIZ], f, n, i, *p, d, n1, n2;
|
||||
filespec fs;
|
||||
|
||||
fs.dev = fp->dev;
|
||||
fs.dir = fp->dir;
|
||||
fs.fn1 = _FILE_;
|
||||
fs.fn2 = _PDIRP_;
|
||||
if (!fs.dev) fs.dev = _DSK_;
|
||||
if (!fs.dir) fs.dir = rsname();
|
||||
f = open (&fs, BII);
|
||||
if (f<0) return (0);
|
||||
sysread (f, buf, DIRSIZ);
|
||||
close (f);
|
||||
n = (DIRSIZ - buf[1]) / ENTSIZ;
|
||||
p = buf+buf[1];
|
||||
i = 0;
|
||||
while (--n >= 0)
|
||||
{n1 = *p++;
|
||||
n2 = *p++;
|
||||
d = *p++ >> 18; /* random info */
|
||||
p =+ 2;
|
||||
if (d & 060) continue; /* should ignore these */
|
||||
if (opt & d) continue; /* optionally ignore */
|
||||
*v++ = n1;
|
||||
*v++ = n2;
|
||||
++i;
|
||||
}
|
||||
return (i);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
RMFD - Read the Master File Directory
|
||||
|
||||
V will be filled with SIXBIT names, one for each directory,
|
||||
sorted.
|
||||
The number of directories is returned.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int rdmfd (v)
|
||||
int v[];
|
||||
|
||||
{int ch, n, *e, *p, *q, i, j, x;
|
||||
|
||||
ch = fopen ("m.f.d. (file)", BII);
|
||||
if (ch<0) return (ch);
|
||||
n = sysread (ch, v, DIRSIZ);
|
||||
close (ch);
|
||||
e = v+n;
|
||||
p = v+v[1];
|
||||
q = v;
|
||||
while (p<e) if (x = *p++) *q++ = x;
|
||||
n = q-v-1; /* -1 for convenience in sort */
|
||||
for (i=0; i<n; ++i)
|
||||
for (j=i; j<=n; ++j)
|
||||
if (v[j] < v[i]) {x=v[i];v[i]=v[j];v[j]=x;}
|
||||
++n;
|
||||
v[n] = 0;
|
||||
return (n);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
a test routine
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
# ifdef test
|
||||
|
||||
main ()
|
||||
|
||||
{char buf[50];
|
||||
|
||||
while (TRUE)
|
||||
{cprint ("Pattern: ");
|
||||
gets (buf);
|
||||
mapdir (buf, prf);
|
||||
}
|
||||
}
|
||||
|
||||
prf (f)
|
||||
filespec *f;
|
||||
|
||||
{char buf[100];
|
||||
prfile (f, buf);
|
||||
cprint ("%s\n", buf);
|
||||
}
|
||||
|
||||
# endif
|
||||
23
src/clib/c10fil.c
Normal file
23
src/clib/c10fil.c
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "c.defs"
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
RENAME (file1, file2)
|
||||
|
||||
Should work even if a file2 already exists.
|
||||
Return 0 if no error.
|
||||
|
||||
*ITS VERSION*
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
rename (s1, s2) char *s1, *s2;
|
||||
|
||||
{filespec fs1, fs2;
|
||||
fparse (s1, &fs1);
|
||||
fparse (s2, &fs2);
|
||||
if (fs1.dev==0) fs1.dev = csto6 ("DSK");
|
||||
sysdelete (&fs2);
|
||||
sysrname (&fs1, &fs2);
|
||||
return (0);
|
||||
}
|
||||
118
src/clib/c10fnm.c
Normal file
118
src/clib/c10fnm.c
Normal file
@@ -0,0 +1,118 @@
|
||||
# include "c/c.defs"
|
||||
|
||||
/*
|
||||
|
||||
ITS filename cluster
|
||||
|
||||
components:
|
||||
DEV:DIR;NAME TYP
|
||||
All components manipulated without punctuation.
|
||||
|
||||
routines:
|
||||
s = fngdv (old, buf) return DEV (in buf)
|
||||
s = fngdr (old, buf) return DIR (in buf)
|
||||
s = fngnm (old, buf) return NAME (in buf)
|
||||
s = fngtp (old, buf) return TYP (in buf)
|
||||
s = fnggn (old, buf) return null GEN (in buf)
|
||||
s = fngat (old, buf) return null ATTR (in buf)
|
||||
s = fnsdf (buf, old, dv, dir, nm, typ, gen, attr)
|
||||
set null components of OLD
|
||||
new value in BUF
|
||||
(ignore 0 args)
|
||||
s = fnsfd (buf, old, dv, dir, nm, typ, gen, attr)
|
||||
set components of OLD
|
||||
new value in BUF
|
||||
(ignore 0 args)
|
||||
fnparse (old, dv, dir, nm, typ, gen, attr)
|
||||
parse OLD into components
|
||||
|
||||
*/
|
||||
|
||||
fnparse (old, dv, dir, nm, typ, gen, attr)
|
||||
char *old, *dv, *dir, *nm, *typ, *gen, *attr;
|
||||
|
||||
{filespec temp;
|
||||
fparse (old, &temp);
|
||||
c6tos (temp.dev, dv);
|
||||
c6tos (temp.dir, dir);
|
||||
c6tos (temp.fn1, nm);
|
||||
c6tos (temp.fn2, typ);
|
||||
gen[0] = 0;
|
||||
attr[0] = 0;
|
||||
}
|
||||
|
||||
char *fngdv (old, buf)
|
||||
char *old, *buf;
|
||||
|
||||
{filespec temp;
|
||||
fparse (old, &temp);
|
||||
c6tos (temp.dev, buf);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
char *fngdr (old, buf)
|
||||
char *old, *buf;
|
||||
|
||||
{filespec temp;
|
||||
fparse (old, &temp);
|
||||
c6tos (temp.dir, buf);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
char *fngnm (old, buf)
|
||||
char *old, *buf;
|
||||
|
||||
{filespec temp;
|
||||
fparse (old, &temp);
|
||||
c6tos (temp.fn1, buf);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
char *fngtp (old, buf)
|
||||
char *old, *buf;
|
||||
|
||||
{filespec temp;
|
||||
fparse (old, &temp);
|
||||
c6tos (temp.fn2, buf);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
char *fnggn (old, buf)
|
||||
char *old, *buf;
|
||||
|
||||
{buf[0] = 0;
|
||||
return (buf);
|
||||
}
|
||||
|
||||
char *fngat (old, buf)
|
||||
char *old, *buf;
|
||||
|
||||
{buf[0] = 0;
|
||||
return (buf);
|
||||
}
|
||||
|
||||
char *fnsdf (buf, old, dv, dir, nm, typ, gen, attr)
|
||||
char *old, *buf, *dv, *dir, *nm, *typ, *gen, *attr;
|
||||
|
||||
{filespec temp;
|
||||
fparse (old, &temp);
|
||||
if (dv && temp.dev==0) temp.dev = csto6 (dv);
|
||||
if (dir && temp.dir==0) temp.dir = csto6 (dir);
|
||||
if (nm && temp.fn1==0) temp.fn1 = csto6 (nm);
|
||||
if (typ && temp.fn2==0) temp.fn2 = csto6 (typ);
|
||||
prfile (&temp, buf);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
char *fnsfd (buf, old, dv, dir, nm, typ, gen, attr)
|
||||
char *old, *buf, *dv, *dir, *nm, *typ, *gen, *attr;
|
||||
|
||||
{filespec temp;
|
||||
fparse (old, &temp);
|
||||
if (dv) temp.dev = csto6 (dv);
|
||||
if (dir) temp.dir = csto6 (dir);
|
||||
if (nm) temp.fn1 = csto6 (nm);
|
||||
if (typ) temp.fn2 = csto6 (typ);
|
||||
prfile (&temp, buf);
|
||||
return (buf);
|
||||
}
|
||||
95
src/clib/c10fo.cmid
Normal file
95
src/clib/c10fo.cmid
Normal file
@@ -0,0 +1,95 @@
|
||||
;
|
||||
; FCOUT - FAST CHARACTER OUTPUT ROUTINES
|
||||
;
|
||||
; This file is ITS dependent.
|
||||
;
|
||||
|
||||
TITLE FCOUT
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
BLKSIZ==200
|
||||
BLKCNT==5*BLKSIZ
|
||||
NL==12
|
||||
CR==15
|
||||
|
||||
; SIOT STUFF
|
||||
|
||||
.UDATA
|
||||
SBUF: BLOCK BLKSIZ
|
||||
SPTR: BLOCK 1
|
||||
SCHN: BLOCK 1
|
||||
SCNT: BLOCK 1
|
||||
.IDATA
|
||||
SBPT: 440700,,SBUF
|
||||
.CODE
|
||||
|
||||
CENTRY OOPN,[NAME]
|
||||
CALL FOPEN,[NAME,[[1]]]
|
||||
JUMPL A,OP$RET ; NEGATIVE FAILURE CODE
|
||||
MOVEM A,SCHN ; ITS CHANNEL (RETURNED)
|
||||
MOVEI B,BLKCNT
|
||||
MOVEM B,SCNT
|
||||
MOVE B,SBPT
|
||||
MOVEM B,SPTR
|
||||
OP$RET: RETURN
|
||||
|
||||
CENTRY OFLS ; FLUSH BUFFER
|
||||
MOVEI C,BLKCNT
|
||||
SUB C,SCNT
|
||||
JUMPLE C,FL$RET
|
||||
MOVE D,SBPT
|
||||
SYSCAL SIOT,[SCHN ? D ? C]
|
||||
FL$RET: MOVE D,SBPT
|
||||
MOVEM D,SPTR
|
||||
MOVEI D,BLKCNT
|
||||
MOVEM D,SCNT
|
||||
RETURN
|
||||
|
||||
CENTRY OUTI,[CC] ; OUTPUT IMAGE CHARACTER
|
||||
MOVE A,CC
|
||||
IDPB A,SPTR
|
||||
SOSG SCNT
|
||||
CALL OFLS
|
||||
RETURN
|
||||
|
||||
CENTRY OUTC,[CC] ; OUTPUT ASCII CHARACTER
|
||||
MOVE A,CC
|
||||
CAIN A,NL
|
||||
GO OC$NL
|
||||
OC$1: IDPB A,SPTR
|
||||
SOSG SCNT
|
||||
CALL OFLS
|
||||
RETURN
|
||||
OC$NL: MOVEI A,CR
|
||||
IDPB A,SPTR
|
||||
SOSG SCNT
|
||||
CALL OFLS
|
||||
MOVEI A,NL
|
||||
GO OC$1
|
||||
|
||||
CENTRY OUTS,[STR] ; OUTPUT ASCII STRING
|
||||
MOVE B,STR
|
||||
OS$2: SKIPN A,(B)
|
||||
GO OS$RET
|
||||
ADDI B,1
|
||||
CAIN A,NL
|
||||
GO OS$NL
|
||||
OS$1: IDPB A,SPTR
|
||||
SOSG SCNT
|
||||
CALL OFLS
|
||||
GO OS$2
|
||||
OS$NL: MOVEI A,CR
|
||||
IDPB A,SPTR
|
||||
SOSG SCNT
|
||||
CALL OFLS
|
||||
MOVEI A,NL
|
||||
GO OS$1
|
||||
OS$RET: RETURN
|
||||
|
||||
CENTRY OCLS ; CLOSE FILE
|
||||
CALL OFLS
|
||||
SYSCAL CLOSE,[SCHN]
|
||||
RETURN
|
||||
|
||||
END
|
||||
406
src/clib/c10int.cmid
Normal file
406
src/clib/c10int.cmid
Normal file
@@ -0,0 +1,406 @@
|
||||
;
|
||||
; INTRUP - C INTERRUPT SYSTEM
|
||||
;
|
||||
; This file is ITS dependent.
|
||||
;
|
||||
|
||||
TITLE INTRUP
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
.GLOBAL UUOH,USAVEA,USAVEB,USAVEC,USAVED
|
||||
.GLOBAL PDLTOP
|
||||
|
||||
; SOME C INTERRUPT NUMBERS
|
||||
|
||||
CH0I==16. ; CHANNEL 0 INTERRUPT
|
||||
IN0I==32. ; INFERIOR 0 INTERRUPT
|
||||
MPV==1. ; MPV INTERRUPT
|
||||
CTRSI==41. ; CONTROL-S INTERRUPT
|
||||
CTRGI==42. ; CONTROL-G INTERRUPT
|
||||
NINT==42. ; NUMBER OF INTERRUPTS
|
||||
|
||||
; TAB1 - CONVERTS FIRST WORD INTERRUPTS TO C INTERRUPT NUMBER
|
||||
|
||||
.PDATA
|
||||
MDATA TAB1
|
||||
0 ? 0 ? 10. ? 0 ? 0 ? 0
|
||||
0 ? 0 ? 0 ? 15. ? 7. ? 6.
|
||||
5. ? 0 ? 0 ? 0 ? 0 ? 0
|
||||
13. ? 0 ? 0 ? 4. ? 1. ? 9.
|
||||
0 ? 0 ? 0 ? 2. ? 0 ? 8.
|
||||
3. ? 0 ? 14. ? 0 ? 0 ? 12.
|
||||
|
||||
; TAB2 - CONTAINS HANDLERS FOR AND INFORMATION ABOUT C INTERRUPTS
|
||||
|
||||
; BITS 0-17 HANDLER (0 => DEFAULT, 1 => IGNORE, OTHER => ROUTINE ADDR)
|
||||
; BITS 18-23 BIT NUMBER IN ITS MASK WORD
|
||||
; BIT 24 ITS MASK WORD NUMBER
|
||||
|
||||
.IDATA
|
||||
MDATA TAB2
|
||||
0 ; NOT USED
|
||||
15,,0 ; MPV
|
||||
10,,0 ; IOC
|
||||
5,,0 ; ILOPR
|
||||
16,,0 ; MAR
|
||||
27,,0 ; UTRAP
|
||||
30,,0 ; PURE
|
||||
31,,0 ; WIRO
|
||||
|
||||
6,,0 ; SYSDOWN
|
||||
14,,0 ; CLOCK
|
||||
41,,0 ; TIMER
|
||||
0 ; PDLOV (NOT USED)
|
||||
0,,0 ; TTYI
|
||||
21,,0 ; CLI
|
||||
3,,0 ; OVERFLOW
|
||||
32,,0 ; FLOATING OVERFLOW
|
||||
|
||||
100,,0 ; CHANNEL 0
|
||||
101,,0 ; CHANNEL 1
|
||||
102,,0 ; CHANNEL 2
|
||||
103,,0 ; CHANNEL 3
|
||||
104,,0 ; CHANNEL 4
|
||||
105,,0 ; CHANNEL 5
|
||||
106,,0 ; CHANNEL 6
|
||||
107,,0 ; CHANNEL 7
|
||||
|
||||
110,,0 ; CHANNEL 10
|
||||
111,,0 ; CHANNEL 11
|
||||
112,,0 ; CHANNEL 12
|
||||
113,,0 ; CHANNEL 13
|
||||
114,,0 ; CHANNEL 14
|
||||
115,,0 ; CHANNEL 15
|
||||
116,,0 ; CHANNEL 16
|
||||
117,,0 ; CHANNEL 17
|
||||
|
||||
122,,0 ; INFERIOR 0
|
||||
123,,0 ; INFERIOR 1
|
||||
124,,0 ; INFERIOR 2
|
||||
125,,0 ; INFERIOR 3
|
||||
126,,0 ; INFERIOR 4
|
||||
127,,0 ; INFERIOR 5
|
||||
130,,0 ; INFERIOR 6
|
||||
131,,0 ; INFERIOR 7
|
||||
|
||||
0 ; NOT USED
|
||||
0 ; CONTROL-S INTERRUPT
|
||||
0 ; CONTROL-G INTERRUPT
|
||||
|
||||
|
||||
;
|
||||
; ON - SPECIFY AN ACTION FOR A C INTERRUPT
|
||||
;
|
||||
|
||||
.CODE
|
||||
CENTRY ON,[INTNO,NEWH]
|
||||
|
||||
MOVE B,INTNO ; INTERRUPT #
|
||||
JUMPLE B,ON2 ; BAD #
|
||||
CAILE B,NINT ; NINT = HIGHEST VALID #
|
||||
GO ON2 ; BAD #
|
||||
HRRZ A,NEWH ; NEW HANDLER
|
||||
CAIL B,CTRSI
|
||||
GO ON1 ; SOFTWARE INTERRUPT
|
||||
|
||||
LDB D,[220600,,TAB2(B)] ; BIT #
|
||||
MOVEI C,1
|
||||
LSH C,(D) ; MASK
|
||||
LDB D,[300100,,TAB2(B)] ; WORD #
|
||||
|
||||
CAIN B,CTRGI
|
||||
JUMPE A,TURNON
|
||||
JUMPE A,TURNOF
|
||||
CAIE A,1
|
||||
GO TURNON
|
||||
CAIGE B,8.
|
||||
GO TURNON
|
||||
|
||||
TURNOF: .SUSET [.SAMASK,,C ? .SAMSK2,,C](D)
|
||||
GO ON1
|
||||
|
||||
TURNON: .SUSET [.SIMASK,,C ? .SIMSK2,,C](D)
|
||||
ON1: HRRZ C,TAB2(B) ; OLD HANDLER
|
||||
HRRM A,TAB2(B) ; NEW HANDLER
|
||||
MOVE A,C ; RETURN OLD HANDLER
|
||||
ONRET: RETURN
|
||||
|
||||
ON2: CROAK ON: INVALID INTERRUPT NUMBER
|
||||
MOVEI A,1
|
||||
GO ONRET
|
||||
|
||||
|
||||
;
|
||||
; SIGNAL - SIGNAL A C INTERRUPT
|
||||
;
|
||||
|
||||
CENTRY SIGNAL,[SIGNO]
|
||||
|
||||
MOVE A,SIGNO ; INTERRUPT #
|
||||
JUMPLE A,S3 ; BAD #
|
||||
CAILE A,NINT ; NINT = HIGHEST VALID #
|
||||
GO S3 ; BAD #
|
||||
HRRZ B,TAB2(A) ; HANDLER
|
||||
CAIN B,1
|
||||
GO SIGRET ; 1 => IGNORE
|
||||
JUMPN B,S1 ; SPECIFIED HANDLER
|
||||
CAIN A,CTRGI
|
||||
GO S4 ; HANDLE ^G INTERRUPT
|
||||
GO SIGRET ; OTHERWISE IGNORE
|
||||
|
||||
S1: CAIGE A,CH0I
|
||||
GO S2 ; NO ARG
|
||||
CAILE A,IN0I+7
|
||||
GO S2 ; NO ARG
|
||||
CAIGE A,IN0I
|
||||
SUBI A,CH0I ; ARG IS CHANNEL #
|
||||
CAIL A,IN0I
|
||||
SUBI A,IN0I ; ARG IS INFERIOR #
|
||||
VCALL (B),[A]
|
||||
GO SIGRET
|
||||
|
||||
S2: CAIN A,CTRSI
|
||||
CL CTRSIH ; SPECIAL ^S ACTION
|
||||
CAIN A,CTRGI
|
||||
CL CTRGIH ; SPECIAL ^G ACTION
|
||||
VCALL (B)
|
||||
GO SIGRET
|
||||
|
||||
S3: CROAK INVALID INTERRUPT SIGNALLED
|
||||
GO SIGRET
|
||||
|
||||
S4: CL CTRGIH
|
||||
CALL STKDMP
|
||||
CROAK -- ^G --
|
||||
SIGRET: RETURN
|
||||
|
||||
; SPECIAL HANDLER FOR CONTROL-S INTERRUPT
|
||||
|
||||
IENTRY CTRSIH
|
||||
|
||||
PPUSH A
|
||||
PPUSH B
|
||||
CTRS1: SETO B,
|
||||
SYSCAL IOT,[5000,,%TIACT+%TIINT+%TINWT ? TYICHN" ? 2000,,B]
|
||||
JUMPLE B,CTRS2
|
||||
CAIE B,^S
|
||||
GO CTRS1
|
||||
CTRS2: PPOP B
|
||||
PPOP A
|
||||
RTN
|
||||
|
||||
; SPECIAL HANDLER FOR CONTROL-G INTERRUPT
|
||||
|
||||
IENTRY CTRGIH
|
||||
|
||||
PPUSH A
|
||||
PPUSH B
|
||||
CTRG1: SETO B,
|
||||
SYSCAL IOT,[5000,,%TIACT+%TIINT+%TINWT ? TYICHN ? 2000,,B]
|
||||
JUMPLE B,CTRG2
|
||||
CAIE A,^G
|
||||
GO CTRG1
|
||||
CTRG2: PPOP B
|
||||
PPOP A
|
||||
RTN
|
||||
|
||||
|
||||
;
|
||||
; DISMISS - DISMISS INTERRUPT AND RETURN TO CALLER
|
||||
;
|
||||
|
||||
MENTRY DISMISS
|
||||
SYSCAL DISMIS,[5000,,T%CTL ? INTPTR ? 1000,,.+2]
|
||||
RETURN
|
||||
|
||||
;
|
||||
; GETPC - GET INTERRUPTED PC
|
||||
;
|
||||
|
||||
CENTRY GETPC
|
||||
MOVE D,INTPTR ; TOP OF INTERRUPT STACK
|
||||
MOVEI D,-T%SIZ+1(D) ; BOTTOM OF FRAME
|
||||
HRRZ A,T%OPC(D)
|
||||
RETURN
|
||||
|
||||
;
|
||||
; SETPC - SET INTERRUPTED PC
|
||||
;
|
||||
|
||||
CENTRY SETPC,[PC]
|
||||
MOVE D,INTPTR ; TOP OF INTERRUPT STACK
|
||||
MOVEI D,-T%SIZ+1(D) ; BOTTOM OF FRAME
|
||||
MOVE A,PC
|
||||
HRRM A,T%OPC(D)
|
||||
RETURN
|
||||
|
||||
;
|
||||
; INTERRUPT HANDLING SPECIFICATONS
|
||||
;
|
||||
|
||||
T%NRG==4 ; NUMBER OF REGISTERS PUSHED
|
||||
|
||||
T%IW1==0 ; OFFSET OF 1ST INTERRUPT WORD
|
||||
T%IW2==1 ; OFFSET OF 2ND INTERRUPT WORD
|
||||
T%DF1==2 ; OFFSET OF 1ST OLD DEFER WORD
|
||||
T%DF2==3 ; OFFSET OF 2ND OLD DEFER WORD
|
||||
T%OPC==4 ; OFFSET OF OLD PC
|
||||
T%REG==5 ; OFFSET OF FIRST SAVED REGISTER
|
||||
T%SIZ==T%REG+T%NRG ; SIZE OF INTERRUPT FRAME
|
||||
T%CTL==A*100+T%NRG ; CONTROL ARG FOR PUSHING REGS
|
||||
|
||||
MDATA TSINT
|
||||
T%CTL,,INTPTR ; PUSH REGISTERS ON INTERRUPT STACK
|
||||
%PIPDL ? 0 ; HANDLE PDL-OVERFLOW
|
||||
-1 ? -1 ; DEFER ALL INTERRUPTS
|
||||
PDLOVH ; PDL-OVERFLOW HANDLER
|
||||
%PIMPV ? 0 ; HANDLE MPV
|
||||
#%PIPDL ? -1 ; DEFER ALL BUT PDL-OVERFLOW
|
||||
MPVH ; MPV HANDLER
|
||||
#<%PIMPV+%PIPDL> ? 0 ; HANDLE ALL OTHER FIRST WORDERS
|
||||
#<%PIMPV+%PIPDL> ? -1 ; DEFER ALL BUT MPV AND PDLOV
|
||||
TSINT1 ; INTERRUPT HANDLER
|
||||
0 ? -1 ; HANDLE ALL SECOND WORDERS
|
||||
#<%PIMPV+%PIPDL> ? -1 ; DEFER ALL BUT MPV AND PDLOV
|
||||
TSINT2 ; INTERRUPT HANDLER
|
||||
TSINTL"==21. ; .-TSINT DOESN'T WORK DUE TO MIDAS BUG
|
||||
|
||||
;
|
||||
; INTERRUPT STACK
|
||||
;
|
||||
|
||||
INTPSZ==2*TSINTL ; SIZE OF INTERRUPT STACK
|
||||
|
||||
.IDATA
|
||||
MDATA INTPTR
|
||||
-INTPSZ,,INTPDL
|
||||
MDATA INTPDL
|
||||
BLOCK INTPSZ-1
|
||||
-1 ; THIS PAGE MUST NOT BE DELETED!
|
||||
.CODE
|
||||
|
||||
;
|
||||
; MPV HANDLER
|
||||
;
|
||||
|
||||
IENTRY MPVH
|
||||
|
||||
.SUSET [.RMPVA,,B] ; GET LOSING ADDRESS
|
||||
; NOTE THAT ON KA-10 THIS ADDRESS
|
||||
; IS ROUNDED DOWN TO FIRST WORD
|
||||
; OF PAGE
|
||||
TRZ B,1777 ; ROUND DOWN ANYWAY (FOR KL-10)
|
||||
|
||||
CAMGE B,SEG0LO" ; MAYBE IN SEGMENT 0?
|
||||
GO MPV$0 ; NO
|
||||
CAMG B,SEG0HI" ; IN SEGMENT 0?
|
||||
GO MPV$1 ; YES
|
||||
|
||||
MPV$0: CAMGE B,SEG1LO" ; MAYBE IN SEGMENT 1?
|
||||
GO TSINT1 ; NO
|
||||
CAMLE B,SEG1HI" ; IN SEGMENT 1?
|
||||
GO TSINT1 ; NO
|
||||
|
||||
; HERE IF ADDRESS IS IN SEGMENT 1
|
||||
|
||||
MOVE C,PDLTOP ; TOP END OF STACK
|
||||
SUBI C,2000
|
||||
TRZ C,1777 ; LAST FULL PAGE OF STACK
|
||||
CAME B,C ; REFERENCE TO LAST PAGE OF STACK?
|
||||
GO MPV$1 ; NO
|
||||
CROAK IMMINENT STACK OVERFLOW
|
||||
|
||||
MPV$1: LSH B,-10. ; PAGE NUMBER
|
||||
SYSCAL CORTYP,[B ? SETZM C] ; GET PAGE INFO
|
||||
JUMPN C,TSINT1 ; PAGE EXISTS => MPV ON ANOTHER JOB
|
||||
|
||||
MPV$2: SYSCAL CORBLK,[1000,,%CBNDW ? 1000,,-1 ? B ? 1000,,%JSNEW],MPVLOS
|
||||
GO INTDIS
|
||||
MPVLOS: CROAK UNABLE TO GET ZERO PAGE
|
||||
GO MPV$2
|
||||
|
||||
;
|
||||
; HANDLER FOR FIRST WORD INTERRUPTS
|
||||
;
|
||||
|
||||
IENTRY TSINT1
|
||||
|
||||
MOVE D,INTPTR ; TOP OF INTERRUPT STACK
|
||||
MOVEI D,-T%SIZ+1(D) ; BOTTOM OF FRAME
|
||||
MOVE A,T%IW1(D) ; GET INTERRUPT WORD
|
||||
JFFO A,.+2 ; GET FIRST BIT
|
||||
GO INTDIS ; NONE (?)
|
||||
MOVE A,TAB1(B) ; C INTERRUPT NUMBER
|
||||
JUMPE A,IGNORE ; NOT HANDLED
|
||||
HRRZ B,TAB2(A) ; HANDLER
|
||||
CAIN B,1
|
||||
GO IGNORE ; 1 MEANS IGNORE
|
||||
JUMPN B,TS1 ; HANDLER SPECIFIED
|
||||
CAIN A,MPV
|
||||
GO FATMPV
|
||||
CAIN A,CTRGI
|
||||
GO TS1 ; DEFAULT IS NOT TO IGNORE
|
||||
IGNORE: AOS T%OPC(D) ; OTHERWISE - THE DEFAULT
|
||||
GO INTDIS ; IS TO CONTINUE WITH THE
|
||||
; NEXT INSTRUCTION
|
||||
|
||||
; HERE IF FATAL MPV OCCURS
|
||||
|
||||
FATMPV: MOVEI A,%PIMPV
|
||||
IORM A,T%DF1(D) ; MAKE MPV DEFFERED
|
||||
GO INTDIS ; NOW DISMISS - WILL MAKE FATAL
|
||||
|
||||
;
|
||||
; SECOND WORD INTERRUPT HANDLER
|
||||
;
|
||||
|
||||
IENTRY TSINT2
|
||||
|
||||
MOVE D,INTPTR ; TOP OF INTERRUPT STACK
|
||||
MOVEI D,-T%SIZ+1(D) ; BOTTOM OF FRAME
|
||||
MOVE A,T%IW2(D) ; GET INTERRUPT WORD
|
||||
JFFO A,.+2
|
||||
GO INTDIS
|
||||
CAILE B,17.
|
||||
GO CHANI
|
||||
CAIGE B,10.
|
||||
GO INTDIS
|
||||
MOVN A,B
|
||||
ADDI A,17.+IN0I
|
||||
GO TS1
|
||||
|
||||
CHANI: CAIGE B,19.
|
||||
GO INTDIS
|
||||
MOVN A,B
|
||||
ADDI A,35.+CH0I
|
||||
GO TS1
|
||||
|
||||
|
||||
;
|
||||
; HERE TO SIGNAL SOMETHING WITH ARG IN A
|
||||
;
|
||||
|
||||
DEFINE PUSHL LIST
|
||||
IRP X,,[LIST]
|
||||
PPUSH X
|
||||
TERMIN!TERMIN
|
||||
|
||||
DEFINE POPL LIST
|
||||
IRP X,,[LIST]
|
||||
PPOP X
|
||||
TERMIN!TERMIN
|
||||
|
||||
TS1: ADDI P,20 ; IN CASE EPILOG INTERRUPTED
|
||||
PUSHL [0,5,6,7,10,11,12,13,14,15,16]
|
||||
PUSHL [40,USAVEA,USAVEB,USAVEC,USAVED,UUOH]
|
||||
CALL SIGNAL,[A]
|
||||
POPL [UUOH,USAVED,USAVEC,USAVEB,USAVEA,40]
|
||||
POPL [16,15,14,13,12,11,10,7,6,5,0]
|
||||
SUBI P,20
|
||||
|
||||
PDLOVH:
|
||||
INTDIS: SYSCAL DISMIS,[5000,,T%CTL ? INTPTR]
|
||||
|
||||
IENTRY ETSINT
|
||||
END
|
||||
848
src/clib/c10io.c
Normal file
848
src/clib/c10io.c
Normal file
@@ -0,0 +1,848 @@
|
||||
# include "c/c.defs"
|
||||
# include "c/its.bits"
|
||||
|
||||
/*
|
||||
*
|
||||
* CIO - C I/O Routines (written in C)
|
||||
*
|
||||
* Routines:
|
||||
*
|
||||
* fd = copen (fname, mode, opt)
|
||||
* c = getchar ()
|
||||
* gets (s)
|
||||
* putchar (c)
|
||||
* puts (s)
|
||||
* ch = mopen (f, mode)
|
||||
* rc = mclose (ch)
|
||||
* rc = fparse (s, f)
|
||||
* s = prfile (f, s)
|
||||
* ch = fopen (fname, mode)
|
||||
* ch = open (&filespec, mode)
|
||||
* argc = fxarg (argc, argv)
|
||||
* n = prsarg (in, out, argv, job)
|
||||
* valret (s)
|
||||
* c6 = ccto6 (c)
|
||||
* c = c6toc (c6)
|
||||
* w = csto6 (s)
|
||||
* s = c6tos (w, s)
|
||||
*
|
||||
* Internal routines:
|
||||
*
|
||||
* c0init () [called by startup routine]
|
||||
* fd = c0open (fname, mode)
|
||||
* w = cons (lh, rh)
|
||||
* s = filscan (b, s)
|
||||
* s = c6q2s (w, s)
|
||||
*
|
||||
* Variables:
|
||||
*
|
||||
* cin - standard input channel
|
||||
* cout - standard output channel
|
||||
* cerr - standard error output channel
|
||||
*
|
||||
* cinfn - standard input file name (if redirected)
|
||||
* coutfn - standard output file name (if redirected)
|
||||
* cerrfn - standard errout file name (if redirected)
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
# rename c0fcbs "C0FCBS"
|
||||
# rename gettab "GETTAB"
|
||||
# rename puttab "PUTTAB"
|
||||
# rename clotab "CLOTAB"
|
||||
# rename gc_bad "GC$BAD"
|
||||
# rename pc_bad "PC$BAD"
|
||||
# rename cl_bad "CL$BAD"
|
||||
# rename prsarg "PRSARG"
|
||||
# rename fcbtab "FCBTBL"
|
||||
# rename tty_input_channel "TYICHN"
|
||||
# rename tty_output_channel "TYOCHN"
|
||||
# rename setappend "SETAPP"
|
||||
|
||||
# define _magic 37621 /* a magic number for validation */
|
||||
# define buf_siz 0200
|
||||
# define fcb_siz 7
|
||||
# define NCHANNEL 10 /* number of CHANNELs */
|
||||
|
||||
# define phyeof_flag 001
|
||||
# define open_flag 002
|
||||
# define write_flag 004
|
||||
# define tty_flag 010
|
||||
# define unset_flag 020
|
||||
|
||||
# define QUOTE 021 /* control-Q, for file names */
|
||||
|
||||
# define _DSK 0446353000000 /* sixbit for DSK */
|
||||
# define _GREATER 0360000000000 /* sixbit for > */
|
||||
# define _TTY 0646471000000 /* sixbit for TTY */
|
||||
# define _FILE 0164651544516 /* sixbit for .FILE. */
|
||||
# define _DIR 0104451621100 /* sixbit for (DIR) */
|
||||
|
||||
channel cin, /* standard input unit */
|
||||
cout, /* standard output unit */
|
||||
cerr; /* standard error output unit */
|
||||
|
||||
char *cinfn, /* standard input file name, if redirected */
|
||||
*coutfn, /* standard output file name, if redirected */
|
||||
*cerrfn; /* standard errout file name, if redirected */
|
||||
|
||||
int cerrno; /* system OPEN error codes returned here */
|
||||
|
||||
extern int c0fcbs[], fcbtab[], puttab[], gettab[], clotab[],
|
||||
gc_bad[], pc_bad[], cl_bad[];
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
COPEN - CIO Open File
|
||||
|
||||
Open a file, given a file name, an optional mode, and an
|
||||
optional options string. The possible modes are
|
||||
|
||||
'r' - read
|
||||
'w' - write
|
||||
'a' - append
|
||||
|
||||
The default mode is read. Normally, I/O is character oriented
|
||||
and produces text files. In particular, the lines of a text
|
||||
file are assumed (by the user) to be separated by newline
|
||||
characters with any conversion to the system format performed
|
||||
by the I/O routines.
|
||||
|
||||
If an options string is given and contains the character "b",
|
||||
then I/O is integer (word) - oriented and produces image files.
|
||||
|
||||
I/O to and from character strings in core is accomplished by
|
||||
including "s" in the options string and supplying a character
|
||||
pointer to the string to be read or written into as the first
|
||||
argument to COPEN. Closing a string open for write will
|
||||
append a NULL character to the string and return a character
|
||||
pointer to that character.
|
||||
|
||||
COPEN returns a CHANNEL, which is a pointer to a control block.
|
||||
The external variables CIN, COUT, and CERR contain already-open
|
||||
channels for standard input, standard output, and standard
|
||||
error output, respectively.
|
||||
|
||||
COPEN returns OPENLOSS in case of error. The system error code is
|
||||
stored in CERRNO.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
channel copen (fname, mode, opt)
|
||||
char *fname;
|
||||
|
||||
{int *fcbp, i, fmode, bmode, its_mode, flags;
|
||||
int chan, buffp, state, bcnt, device, c, sflag, *ip;
|
||||
char *p, buf[5], *ep;
|
||||
filespec f;
|
||||
|
||||
cerrno = 0;
|
||||
if (mode<'A' || mode>'z') mode = 'r';
|
||||
p = opt;
|
||||
if (opt<0100 || opt>=01000000) p = "";
|
||||
else if (p[0]<'A' || p[0]>'z') p = "";
|
||||
|
||||
flags = open_flag;
|
||||
fmode = 0;
|
||||
switch (lower (mode)) {
|
||||
case 'r': fmode = 0; break;
|
||||
case 'w': fmode = 1; break;
|
||||
case 'a': fmode = 2; break;
|
||||
default: cerrno = 012; /* mode not available */
|
||||
return (OPENLOSS);
|
||||
}
|
||||
bmode = 0;
|
||||
sflag = FALSE;
|
||||
while (c = *p++) switch (lower (c)) {
|
||||
case 'b': bmode = 4; break;
|
||||
case 's': sflag = TRUE; break;
|
||||
}
|
||||
|
||||
if (c0fcbs[0] != _magic) c0init(); /* initialize */
|
||||
for (i=0; i<NCHANNEL; ++i)
|
||||
{fcbp = fcbtab[i];
|
||||
if (!(fcbp[0] & open_flag)) break;
|
||||
}
|
||||
if (i>=NCHANNEL)
|
||||
{cerrno = 06; /* device full */
|
||||
return (OPENLOSS);
|
||||
}
|
||||
chan = -1;
|
||||
buffp = fcbp[0] >> 18;
|
||||
if (sflag) /* string I/O */
|
||||
{state = 3;
|
||||
if (fmode==2) /* append */
|
||||
while (*fname) ++fname;
|
||||
}
|
||||
else /* file I/O */
|
||||
{state = 1;
|
||||
fparse (fname, &f); /* parse file name */
|
||||
if (f.dev == _TTY /* TTY special case */
|
||||
&& (f.fn1 != _FILE || f.fn2 != _DIR))
|
||||
{state = 0;
|
||||
bmode = 0;
|
||||
device = 0;
|
||||
chan = -1;
|
||||
flags =| tty_flag;
|
||||
}
|
||||
else /* normal case */
|
||||
{if (f.dev == 0) f.dev = _DSK;
|
||||
if (f.dir == 0) f.dir = rsname();
|
||||
if (f.fn2 == 0) f.fn2 = _GREATER;
|
||||
|
||||
its_mode = (fmode==2 ? 0100001 : fmode);
|
||||
its_mode =| 2; /* block mode */
|
||||
its_mode =| bmode; /* image mode */
|
||||
|
||||
if (fmode==2 && !bmode) /* char append */
|
||||
{chan = setappend (&f, its_mode, buf, &ep);
|
||||
if (chan == -04) /* not found */
|
||||
{chan = mopen (&f, its_mode & 077);
|
||||
fmode = 1;
|
||||
}
|
||||
}
|
||||
else chan = mopen (&f, its_mode);
|
||||
if (chan<0) {cerrno = -chan; return (OPENLOSS);}
|
||||
device = status (chan) & 077; /* device code */
|
||||
if (bmode && device<=2) /* TTY in IMAGE mode ?? */
|
||||
{close (chan);
|
||||
bmode = 0;
|
||||
its_mode =& ~4;
|
||||
chan = mopen (&f, its_mode);
|
||||
if (chan<0) {cerrno = -chan; return (OPENLOSS);}
|
||||
device = status (chan) & 077;
|
||||
}
|
||||
if (state==1)
|
||||
if (buffp==0)
|
||||
{buffp = salloc (buf_siz);
|
||||
if (buffp == -1)
|
||||
{cerrno = 037; /* no core available */
|
||||
return (OPENLOSS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{i = buf_siz;
|
||||
ip = buffp;
|
||||
while (--i >= 0) *ip++ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
bcnt = -1; /* special initialization hack */
|
||||
if (fmode)
|
||||
{bcnt = 5*buf_siz; /* char count */
|
||||
if (bmode) bcnt = buf_siz; /* word count */
|
||||
flags =| write_flag;
|
||||
}
|
||||
if (bmode && !sflag) state = 2;
|
||||
if (chan < 0) {flags =| unset_flag; chan = 0;}
|
||||
fcbp[0] = (buffp<<18) | ((chan&017)<<14) | ((device&077)<<8) | flags;
|
||||
fcbp[2] = bcnt;
|
||||
if (sflag) fcbp[1] = fname;
|
||||
else fcbp[1] = cons (bmode ? 0 : 0440700, buffp);
|
||||
if (fcbp[3]==0) fcbp[3] = salloc(20);
|
||||
else fcbp[3] =& 0777777;
|
||||
if (fmode) state =+ 4;
|
||||
fcbp[4] = cons (clotab[state], fcbp[5]=gettab[state]);
|
||||
fcbp[6] = puttab[state];
|
||||
if (fmode==2 && !sflag) /* file append */
|
||||
{i = fillen (chan);
|
||||
if (bmode) access (chan, i); /* access to end of file */
|
||||
else if (i>0)
|
||||
{access (chan, i-1); /* write over last word */
|
||||
p = buf;
|
||||
while (p < ep) cputc (*p++ | 0400, fcbp);
|
||||
}
|
||||
}
|
||||
return (fcbp);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
SETAPPEND - Set up for character append
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int setappend (fp, mode, buf, epp) filespec *fp; char buf[], **epp;
|
||||
|
||||
{int count, n, chan, wordlen, chanlen, c;
|
||||
char *p;
|
||||
|
||||
count = 5; /* try 5 times */
|
||||
while (--count>=0)
|
||||
{p = buf;
|
||||
chan = mopen (fp, UII);
|
||||
if (chan < 0) return (chan);
|
||||
wordlen = fillen (chan);
|
||||
close (chan);
|
||||
chan = mopen (fp, UAI);
|
||||
if (chan < 0) return (chan);
|
||||
chanlen = fillen (chan);
|
||||
if (chanlen > 0)
|
||||
{if (chanlen == wordlen) --chanlen;
|
||||
else chanlen = ((chanlen-1)/5)*5;
|
||||
access (chan, chanlen);
|
||||
n = 5;
|
||||
while (--n>=0 && (c = uiiot (chan)) >= 0 && c != 3)
|
||||
*p++ = c;
|
||||
}
|
||||
close (chan);
|
||||
*epp = p;
|
||||
chan = mopen (fp, mode);
|
||||
if (chan<0) return (chan);
|
||||
if (wordlen == fillen(chan)) return (chan);
|
||||
close (chan);
|
||||
}
|
||||
return (-012);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
GETCHAR - Read a character from the standard input unit
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
getchar () {return (cgetc (cin));}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
GETS - Read a string from the standard input unit
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
gets (p)
|
||||
char *p;
|
||||
|
||||
{int c;
|
||||
|
||||
while ((c = cgetc (cin)) != '\n' && c>0) *p++ = c;
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PUTCHAR - Output a character to the standard output unit
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
putchar (c)
|
||||
int c;
|
||||
|
||||
{return (cputc (c, cout));}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PUTS - Output a string to the standard output unit
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
puts (s)
|
||||
char *s;
|
||||
|
||||
{int c;
|
||||
|
||||
while (c = *s++) cputc (c, cout);
|
||||
cputc ('\n', cout);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
MOPEN - OPEN FILE
|
||||
|
||||
Open file given filespec and mode.
|
||||
Return ITS channel number or -FC if unsuccessful.
|
||||
Same as OPEN, except handles TTY specially
|
||||
and waits if file is locked.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
channel mopen (f, mode) filespec *f; int mode;
|
||||
|
||||
{int ch, n;
|
||||
|
||||
if (f->dev == _TTY && !(f->fn1 == _FILE && f->fn2 == _DIR))
|
||||
return (mode & 1 ? tyoopn() : tyiopn());
|
||||
|
||||
ch = open (f, mode);
|
||||
n = 8;
|
||||
while (ch == -023 && --n>=0) /* file locked */
|
||||
{sleep (30);
|
||||
ch = open (f, mode);
|
||||
}
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
MCLOSE - Close ITS channel, unless its the TTY.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
mclose (ch) channel ch;
|
||||
|
||||
{extern int tty_input_channel, tty_output_channel;
|
||||
if (ch == tty_input_channel) return (0);
|
||||
if (ch == tty_output_channel)
|
||||
{tyo_flush ();
|
||||
return (0);
|
||||
}
|
||||
return (close (ch));
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
FPARSE - Convert an ASCIZ string representation of an ITS
|
||||
file name or a path name to a FILESPEC.
|
||||
|
||||
Return 0 if OK, -1 if bad path name format.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
fparse (s, f) char s[]; filespec *f;
|
||||
|
||||
{int i, c, fnc, n_slash, no_its_chars, n_dot;
|
||||
char buf[7], *p, *filscan();
|
||||
|
||||
f->dev = f->dir = f->fn1 = f->fn2 = 0;
|
||||
|
||||
/* check for path name */
|
||||
|
||||
p = s;
|
||||
no_its_chars = TRUE;
|
||||
n_slash = n_dot = 0;
|
||||
|
||||
while (c = *p++) switch (c) {
|
||||
case QUOTE: if (*p) ++p; break;
|
||||
case '.': ++n_dot; break;
|
||||
case '/': ++n_slash; break;
|
||||
case ' ':
|
||||
case ':':
|
||||
case ';': no_its_chars = FALSE; break;
|
||||
}
|
||||
|
||||
if (no_its_chars && (n_dot>0 || n_slash>0))
|
||||
|
||||
/* here if path name */
|
||||
|
||||
{p = s;
|
||||
if (*p=='/')
|
||||
{--n_slash;
|
||||
p = filscan (buf, ++p, &n_dot, &n_slash);
|
||||
f->dev = csto6(buf);
|
||||
c = *p++;
|
||||
if (c!='/') return (-1);
|
||||
}
|
||||
p = filscan (buf, p, &n_dot, &n_slash);
|
||||
c = *p++;
|
||||
if (c=='/')
|
||||
{f->dir = csto6(buf);
|
||||
p = filscan (buf, p, &n_dot, &n_slash);
|
||||
c = *p++;
|
||||
}
|
||||
if (c=='.')
|
||||
{f->fn1 = csto6(buf);
|
||||
p = filscan (buf, p, &n_dot, &n_slash);
|
||||
c = *p++;
|
||||
}
|
||||
if (f->fn1) f->fn2 = csto6(buf);
|
||||
else f->fn1 = csto6(buf);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* here if ITS file name */
|
||||
|
||||
p = s;
|
||||
fnc = i = 0;
|
||||
buf[0] = 0;
|
||||
|
||||
do {c = *p++;
|
||||
switch (c) {
|
||||
|
||||
case ':': f->dev = csto6(buf);
|
||||
i = 0;
|
||||
break;
|
||||
|
||||
case ';': f->dir = csto6(buf);
|
||||
i = 0;
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
case 0: if (buf[0]) switch (fnc++) {
|
||||
case 0: f->fn1 = csto6(buf); break;
|
||||
case 1: f->fn2 = csto6(buf); break;
|
||||
}
|
||||
i = 0;
|
||||
break;
|
||||
|
||||
default: if (c==QUOTE && *p) c = *p++;
|
||||
if (i<6) buf[i++] = c;
|
||||
}
|
||||
|
||||
buf[i] = 0;
|
||||
}
|
||||
while (c);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
FILSCAN - scan for part of file name
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
char *filscan (b, q, andot, anslash)
|
||||
char *b, *q;
|
||||
int *andot, *anslash;
|
||||
|
||||
{int c;
|
||||
char *p;
|
||||
|
||||
p = q++;
|
||||
while (c = *p++)
|
||||
{if (c=='/') {--*anslash; break;}
|
||||
else if (c=='.')
|
||||
{if (--*andot == 0 && *anslash==0 && *p &&
|
||||
p!=q) break;}
|
||||
else if (c==QUOTE && *p) c = *p++;
|
||||
*b++ = c;
|
||||
}
|
||||
*b = 0;
|
||||
return (--p);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PRFILE - convert FILESPEC to ITS file name
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
char *prfile(f,p) filespec *f; char *p;
|
||||
|
||||
{char *c6q2s();
|
||||
if (f->dev) {p = c6q2s (f->dev, p); *p++ = ':';}
|
||||
if (f->dir) {p = c6q2s (f->dir, p); *p++ = ';';}
|
||||
if (f->fn1) {p = c6q2s (f->fn1, p); *p++ = ' ';}
|
||||
if (f->fn2) {p = c6q2s (f->fn2, p);}
|
||||
*p = 0;
|
||||
return (p);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
FOPEN - Open file given file name
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
channel fopen (fname, mode) char *fname; int mode;
|
||||
|
||||
{filespec f;
|
||||
|
||||
fparse (fname, &f);
|
||||
if (f.dev == 0) f.dev = _DSK;
|
||||
if (f.dir == 0) f.dir = rsname();
|
||||
return (open (&f, mode));
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
OPEN - Open file given filespec
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
channel open (f, mode) filespec *f; int mode;
|
||||
|
||||
{channel c;
|
||||
int rc;
|
||||
|
||||
c = chnloc();
|
||||
if (c<0) return (-014); /* bad channel number */
|
||||
rc = sysopen (c, f, mode);
|
||||
if (rc) return (rc);
|
||||
return (c);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
FXARG - Process Command Arguments to Set Up
|
||||
Redirection of Standard Input and Output
|
||||
|
||||
This routine is called by the C start-up routine.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int fxarg (argc, argv) int argc; char *argv[];
|
||||
|
||||
{char **p, **q, *s;
|
||||
int i, append, errappend, f;
|
||||
|
||||
i = argc; /* number of arguments given */
|
||||
argc = 0; /* number of arguments returned */
|
||||
p = argv; /* source pointer */
|
||||
q = argv; /* destination pointer */
|
||||
|
||||
while (--i >= 0) /* for each argument given */
|
||||
{s = *p++; /* the argument */
|
||||
switch (s[0]) {
|
||||
case '<': if (s[1]) cinfn = s+1; break;
|
||||
case '>': if (s[1] == '>')
|
||||
{if (s[2]) {coutfn = s+2; append = TRUE;}}
|
||||
else {if (s[1]) {coutfn = s+1; append = FALSE;}}
|
||||
break;
|
||||
case '%': if (s[1] == '%')
|
||||
{if (s[2]) {cerrfn = s+2; errappend=TRUE;}}
|
||||
else {if (s[1]) {cerrfn = s+1; errappend = FALSE;}}
|
||||
break;
|
||||
default: /* normal argument */
|
||||
++argc; *q++ = s;
|
||||
}
|
||||
}
|
||||
|
||||
/* now hack the standard file descriptors */
|
||||
|
||||
if (cinfn) /* input is redirected */
|
||||
{f = c0open (cinfn, 'r');
|
||||
if (f != OPENLOSS) {cclose (cin); cin = f;}
|
||||
}
|
||||
|
||||
if (coutfn) /* output is redirected */
|
||||
{f = c0open (coutfn, append ? 'a' : 'w');
|
||||
if (f != OPENLOSS) {cout = f;}
|
||||
}
|
||||
|
||||
if (cerrfn) /* errout is redirected */
|
||||
{f = c0open (cerrfn, errappend ? 'a' : 'w');
|
||||
if (f != OPENLOSS)
|
||||
{if (cerr!=cout) cclose (cerr); cerr = f;}
|
||||
}
|
||||
return (argc);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
C0OPEN - Open with error message
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
channel c0open (name, mode)
|
||||
|
||||
{channel f;
|
||||
|
||||
f = copen (name, mode, 0);
|
||||
if (f == OPENLOSS) cprint (cerr, "Unable to open '%s'\n", name);
|
||||
return (f);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
C0INIT - Initialization for C I/O Routines.
|
||||
This routine is normally called first by the C start-up routine.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
c0init ()
|
||||
|
||||
{int *p, i;
|
||||
|
||||
c0fcbs[0] = _magic;
|
||||
p = &c0fcbs[1];
|
||||
i = NCHANNEL*fcb_siz;
|
||||
while (--i >= 0) *p++ = 0;
|
||||
i = NCHANNEL;
|
||||
while (--i >= 0)
|
||||
{p = &c0fcbs[fcb_siz*i+5];
|
||||
p[0] = cons (cl_bad, gc_bad);
|
||||
p[1] = gc_bad;
|
||||
p[2] = pc_bad;
|
||||
}
|
||||
|
||||
cin = copen ("/tty", 'r', 0); /* standard input */
|
||||
cout = cerr = copen ("/tty", 'w', 0); /* standard output */
|
||||
|
||||
/* These calls do not actually open the TTY, the TTY is
|
||||
automatically opened when I/O is done to it. This is helpful
|
||||
for allowing C programs to run without the TTY. */
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
VALRET - Valret a String
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
valret (s) char *s;
|
||||
|
||||
{int len, bp1, bp2, buf, c, flag;
|
||||
|
||||
flag = FALSE;
|
||||
len = slen (s);
|
||||
buf = salloc (len/5 + 1);
|
||||
if (buf<=0)
|
||||
{buf=s; /* gross hack */
|
||||
flag = TRUE;
|
||||
}
|
||||
bp1 = bp2 = 0440700000000 | buf;
|
||||
|
||||
while (TRUE)
|
||||
{c = *s++;
|
||||
if (c=='\n') c='\r';
|
||||
idpb (c, &bp1);
|
||||
if (!c) break;
|
||||
}
|
||||
|
||||
val7ret (bp2);
|
||||
if (flag) cquit(1); else sfree (buf);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PRSARG - Parse JCL Arguments (PDP-10 ITS)
|
||||
|
||||
given: in - an advance byte pointer to the JCL
|
||||
out - a pointer to a character buffer where the
|
||||
arguments should be placed
|
||||
argv - a pointer to a character pointer array
|
||||
where pointers to the args should be placed
|
||||
job - the sixbit XJNAME
|
||||
narg - the maximum number of arguments
|
||||
returns: number of arguments
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int prsarg (in, out, argv, job, narg)
|
||||
char *out, *argv[];
|
||||
|
||||
{int c, argc;
|
||||
char *c6tos();
|
||||
|
||||
argc = 1;
|
||||
argv[0] = out;
|
||||
out = c6tos (job, out);
|
||||
*out++ = 0;
|
||||
argv[1] = out;
|
||||
|
||||
while (c = ildb (&in))
|
||||
{switch (c) {
|
||||
case '\r': break;
|
||||
case QUOTE: *out++ = ildb (&in); continue;
|
||||
case ' ': continue;
|
||||
case '"': while (c = ildb (&in))
|
||||
{switch (c) {
|
||||
case '\r': break;
|
||||
case QUOTE: *out++ = ildb (&in); continue;
|
||||
case '"': break;
|
||||
default: *out++ = c; continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
*out++ = 0;
|
||||
if (++argc < narg) argv[argc] = out;
|
||||
if (c=='"') continue;
|
||||
break;
|
||||
default: *out++ = c;
|
||||
while (c = ildb (&in))
|
||||
{switch (c) {
|
||||
case '\r': break;
|
||||
case ' ': break;
|
||||
case QUOTE: *out++ = ildb (&in); continue;
|
||||
default: *out++ = c; continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
*out++ = 0;
|
||||
if (++argc < narg) argv[argc] = out;
|
||||
if (c==' ') continue;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (argc>narg ? narg : argc);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
CONS - construct word from left and right halves
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int cons (lh, rh) {return (((lh & 0777777) << 18) | (rh & 0777777));}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
CCTO6 - convert ascii character to sixbit character
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
char ccto6 (c) char c;
|
||||
|
||||
{return (((c>=040 && c<0140) ? c+040 : c) & 077);}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
C6TOC - convert sixbit character to ascii character
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
char c6toc (c) char c;
|
||||
|
||||
{return (c+040);}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
CSTO6 - convert ascii string to left-justified sixbit
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int csto6 (s) char *s;
|
||||
|
||||
{int c,i,j;
|
||||
|
||||
i=0;
|
||||
j=30;
|
||||
while (c = *s++) if (j>=0)
|
||||
{i =| (ccto6(c)<<j);
|
||||
j =- 6;
|
||||
}
|
||||
return (i);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
C6TOS - convert left-justified sixbit word to ascii string
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
char *c6tos (i, p) int i; char *p;
|
||||
|
||||
{int c,j;
|
||||
|
||||
j = 30;
|
||||
while (j>=0 && (c = (i>>j)&077))
|
||||
{*p++ = c6toc(c); j =- 6;}
|
||||
*p = 0;
|
||||
return (p);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
C6Q2S - convert left-justified sixbit word to ascii string,
|
||||
inserting QUOTE characters, where necessary
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
char *c6q2s (i, p) int i; char *p;
|
||||
|
||||
{int c, j;
|
||||
|
||||
j = 30;
|
||||
while (j>=0)
|
||||
{c = c6toc ((i>>j) & 077);
|
||||
if (c==' ' || c==':' || c==';') *p++ = QUOTE;
|
||||
*p++ = c;
|
||||
if (! (i & ((1<<j) - 1))) break;
|
||||
j =- 6;
|
||||
}
|
||||
*p = 0;
|
||||
return (p);
|
||||
}
|
||||
|
||||
719
src/clib/c10job.c
Normal file
719
src/clib/c10job.c
Normal file
@@ -0,0 +1,719 @@
|
||||
# include "clib/c.defs"
|
||||
# include "clib/its.bits"
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
JOBs - Inferior Process Management
|
||||
ITS Version
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
The representation of a job is an integer with a value from
|
||||
0 to 7, indicating the inferior number.
|
||||
|
||||
Routines:
|
||||
|
||||
j_create (jname) => # or error code
|
||||
|
||||
j_load (filespec) => # or error code
|
||||
j_fload (file_name) => # or error code
|
||||
j_cload (channel, jname) => # or error code
|
||||
j_own (uname, jname) => # or error code
|
||||
|
||||
error code:
|
||||
|
||||
-1 unable to open program file
|
||||
-2 unable to create job
|
||||
-3 unable to load job
|
||||
-4 fatal error
|
||||
-5 (OWN) no such job
|
||||
-6 (OWN) job not yours
|
||||
|
||||
j_start (#) => rc (return code: non-zero => error)
|
||||
j_stop (#) => rc
|
||||
j_disown (#) => rc
|
||||
j_forget (#) => rc
|
||||
j_kill (#) => rc
|
||||
j_snarf (#, inferior_name) => rc
|
||||
(disown named inferior from stopped job)
|
||||
j_give_tty (#) => rc
|
||||
j_take_tty (#) => rc
|
||||
|
||||
j_grab_tty () (grab tty if given to some inferior
|
||||
and stop job)
|
||||
j_retn_tty () (return tty to inferior and restart)
|
||||
|
||||
j_wait (#) => status (waits for non-zero status)
|
||||
j_sts (#) => status
|
||||
|
||||
j_onchange (f) (set handler for status changes)
|
||||
|
||||
j_sjcl (#, s) => rc (set jcl for job)
|
||||
j_jcl (#) => s (get jcl)
|
||||
j_ch (#) => ch (return block image output channel to job)
|
||||
j_name (#, filespec) (set filespec to job name)
|
||||
|
||||
j_val (#) => s (return string valretted by job)
|
||||
j_fval (#) (flush valret string; or call cfree)
|
||||
|
||||
Job Status:
|
||||
|
||||
-5 => stopped, ^Z typed
|
||||
-4 => stopped (by superior)
|
||||
-3 => stopped, valret
|
||||
-2 => stopped, requested suicide
|
||||
-1 => no job
|
||||
0 => running
|
||||
>0 => stopped, value is job's first interrupt word
|
||||
|
||||
*/
|
||||
|
||||
# define MAXJOBS 8
|
||||
# define VALBUFSIZ 200
|
||||
|
||||
/* job status values */
|
||||
|
||||
# define js_attn -5
|
||||
# define js_stopped -4
|
||||
# define js_valret -3
|
||||
# define js_suicide -2
|
||||
# define js_nojob -1
|
||||
# define js_running 0
|
||||
|
||||
/* useful SIXBIT numbers */
|
||||
|
||||
/* Fixed by BGS 9/14/79 because of MOVNI bug
|
||||
# define _USR 0656362000000
|
||||
# define _TS 0646300000000
|
||||
# define _DSK 0446353000000
|
||||
# define _FOO 0465757000000
|
||||
# define _GR 0360000000000 */ /* > */
|
||||
|
||||
#define _USR csto6("USR")
|
||||
#define _TS csto6("TS")
|
||||
#define _DSK csto6("DSK")
|
||||
#define _FOO csto6("FOO")
|
||||
#define _GR csto6(">")
|
||||
|
||||
/* internal tables */
|
||||
|
||||
# rename job_channels "JOBCHN"
|
||||
# rename job_status "JOBSTS"
|
||||
# rename job_jcl "JOBJCL"
|
||||
# rename job_valret "JOBVAL"
|
||||
# rename job_name "JOBNAM"
|
||||
# rename job_xname "JOBXNM"
|
||||
# rename job_wait "JOBWAT"
|
||||
|
||||
int job_status[MAXJOBS] {js_nojob, js_nojob, js_nojob, js_nojob,
|
||||
js_nojob, js_nojob, js_nojob, js_nojob};
|
||||
int job_channels[MAXJOBS] {-1, -1, -1, -1, -1, -1, -1, -1};
|
||||
char *job_jcl[MAXJOBS];
|
||||
char *job_valret[MAXJOBS];
|
||||
int job_name[MAXJOBS];
|
||||
int job_xname[MAXJOBS];
|
||||
int job_wait -1;
|
||||
static int jobtty {-1}, jobotty, jobosts, (*jchandler)();
|
||||
|
||||
/* the routines */
|
||||
|
||||
int j_fload (file_name) char *file_name;
|
||||
|
||||
{filespec f;
|
||||
|
||||
fparse (file_name, &f);
|
||||
return (j_load (&f));
|
||||
}
|
||||
|
||||
int j_load (f) filespec *f;
|
||||
|
||||
{int pch, xjname;
|
||||
|
||||
if (f->dev == 0) f->dev = _DSK;
|
||||
if (f->dir == 0) f->dir = rsname ();
|
||||
pch = mopen (f, BII);
|
||||
if (pch<0) return (-1);
|
||||
xjname = (f->fn1 == _TS ? f->fn2 : f->fn1);
|
||||
return (j_cload (pch, xjname));
|
||||
}
|
||||
|
||||
int j_cload (pch, xjname)
|
||||
channel pch;
|
||||
|
||||
{int j, jch, start;
|
||||
|
||||
j = j_create (xjname);
|
||||
if (j<0)
|
||||
{close (pch);
|
||||
return (j);
|
||||
}
|
||||
jch = job_channels[j];
|
||||
|
||||
/* load program */
|
||||
|
||||
if (sysload (jch, pch))
|
||||
{uclose (jch);
|
||||
close (pch);
|
||||
return (-3);
|
||||
}
|
||||
|
||||
/* get starting address of program */
|
||||
|
||||
sysread (pch, &start, 1);
|
||||
close (pch);
|
||||
|
||||
/* set starting address of job */
|
||||
|
||||
wuset (jch, UPC, start & 0777777);
|
||||
return (j);
|
||||
}
|
||||
|
||||
int j_create (xjname)
|
||||
|
||||
{int jch, i, inc, count, flag;
|
||||
filespec jf;
|
||||
|
||||
/* set up job name */
|
||||
|
||||
jf.dev = _USR;
|
||||
jf.dir = 0;
|
||||
jf.fn1 = 0;
|
||||
jf.fn2 = xjname;
|
||||
|
||||
/* make job name unique */
|
||||
|
||||
flag = FALSE;
|
||||
while ((jch = open (&jf, OLD + BII)) >= 0)
|
||||
{close (jch);
|
||||
if (!flag)
|
||||
{flag = TRUE;
|
||||
i = jf.fn2;
|
||||
count = 0;
|
||||
while ((i&077)==0) {i =>> 6; ++count;}
|
||||
if (count>0)
|
||||
{count = 6*(count-1);
|
||||
jf.fn2 =| ccto6('0') << count;
|
||||
inc = 1 << count;
|
||||
}
|
||||
else
|
||||
{jf.fn2 = (jf.fn2 & ~077) | ccto6('0');
|
||||
inc = 1;
|
||||
}
|
||||
}
|
||||
else jf.fn2 =+ inc;
|
||||
}
|
||||
|
||||
/* create job */
|
||||
|
||||
jch = open (&jf, BIO);
|
||||
if (jch<0) return (-2);
|
||||
reset (jch);
|
||||
|
||||
/* set job's NAMEs */
|
||||
|
||||
wuset (jch, USNAME, rsname());
|
||||
wuset (jch, UXJNAME, xjname);
|
||||
|
||||
return (j_xxx (jch, xjname));
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
J_OWN - attach job as inferior
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int j_own (uname, jname)
|
||||
|
||||
{filespec fs;
|
||||
int jch, j, w, sts;
|
||||
|
||||
fs.dev = _USR;
|
||||
fs.dir = 0;
|
||||
fs.fn1 = uname;
|
||||
fs.fn2 = jname;
|
||||
|
||||
if ((jch = open (&fs, OLD + BII)) < 0) return (-5);
|
||||
close (jch);
|
||||
if ((jch = open (&fs, BIO)) < 0) return (-5);
|
||||
if (status (jch) != 061)
|
||||
{close (jch); return (-6);}
|
||||
j = j_xxx (jch, jname);
|
||||
if (ruset (jch, USTOP) & BUSRC)
|
||||
{w = ruset (jch, UPIRQ);
|
||||
if (w & PICZ) sts = js_attn;
|
||||
else if (w & PIVAL) sts = js_valret;
|
||||
else if (w) sts = w;
|
||||
else sts = js_stopped;
|
||||
wuset (jch, UAPIRQ, PJTTY+PIIOC+PIARO+PICZ+PIVAL);
|
||||
}
|
||||
else sts = js_running;
|
||||
job_status[j] = sts;
|
||||
return (j);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
J_XXX - common processing for new inferior
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int j_xxx (jch, xjname)
|
||||
|
||||
{int i, inf_no, option, j_handler();
|
||||
|
||||
/* get inferior number */
|
||||
|
||||
i = ruset (jch, UINF) >> 18;
|
||||
inf_no = 0;
|
||||
if (i) while (!(i&1)) {i=>>1; ++inf_no;}
|
||||
|
||||
/* set up interrupt handler */
|
||||
|
||||
on (inferior0_interrupt+inf_no, j_handler);
|
||||
option = ruset (jch, UOPTION);
|
||||
wuset (jch, UOPTION, option | OPTBRK);
|
||||
|
||||
/* clean up */
|
||||
|
||||
job_channels[inf_no] = jch;
|
||||
if (job_status[inf_no] == js_nojob)
|
||||
{job_status[inf_no] = js_stopped;
|
||||
job_jcl[inf_no] = 0;
|
||||
job_valret[inf_no] = 0;
|
||||
}
|
||||
job_name[inf_no] = ruset (jch, UJNAME);
|
||||
job_xname[inf_no] = xjname;
|
||||
|
||||
return (inf_no);
|
||||
}
|
||||
|
||||
int j_start (j)
|
||||
|
||||
{int ch;
|
||||
|
||||
if (j<0 || j>=MAXJOBS) return (-1);
|
||||
ch = job_channels[j];
|
||||
if (ch<0) return (-1);
|
||||
wuset (ch, USTOP, 0);
|
||||
job_status[j] = js_running;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int j_stop (j)
|
||||
|
||||
{int ch;
|
||||
|
||||
if (j<0 || j>=MAXJOBS) return (-1);
|
||||
ch = job_channels[j];
|
||||
if (ch<0) return (-1);
|
||||
wuset (ch, USTOP, -1);
|
||||
job_status[j] = js_stopped;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int j_disown (j)
|
||||
|
||||
{int ch, ec;
|
||||
|
||||
if (j<0 || j>=MAXJOBS) return (-1);
|
||||
ch = job_channels[j];
|
||||
if (ch < 0) return (-1);
|
||||
ec = sysdisown (ch);
|
||||
if (ec) return (ec);
|
||||
j_flush (j);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int j_forget (j)
|
||||
|
||||
{int ch;
|
||||
if (j<0 || j>=MAXJOBS) return (-1);
|
||||
ch = job_channels[j];
|
||||
if (ch < 0) return (-1);
|
||||
close (ch);
|
||||
j_flush (j);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int j_kill (j)
|
||||
|
||||
{int ch;
|
||||
|
||||
if (j<0 || j>=MAXJOBS) return (-1);
|
||||
ch = job_channels[j];
|
||||
if (ch<0) return (-1);
|
||||
uclose (ch);
|
||||
j_flush (j);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int code[] {
|
||||
0042000000013, /* .IOPUSH 0, ;(26) DON'T CLOBBER HIM */
|
||||
0041000000034, /* .OPEN 0,34 ;(27) OPEN <JOB> */
|
||||
0043100000000, /* .LOSE ;(30) FAIL, CAUSE ERR MSG */
|
||||
0042000000027, /* .DISOWN 0, ;(31) DISOWN <JOB> */
|
||||
0042000000014, /* .IOPOP 0, ;(32) UNCLOBBER HIM */
|
||||
0043200000000, /* .VALUE ;(33) RETURN SUCCESS */
|
||||
0000001656362, /* 1,,'USR ;(34) FILENAME BLOCK */
|
||||
0, /* ;(35) WILL GET UNAME */
|
||||
0 /* ;(36) WILL GET JNAME */
|
||||
};
|
||||
|
||||
int j_snarf (j, jname)
|
||||
|
||||
{int ch, piclr, pirqc, pc, osts, sts;
|
||||
|
||||
if (j<0 || j>=MAXJOBS) return (-1);
|
||||
osts = job_status[j];
|
||||
if (osts == js_running) return (-1); /* must be stopped */
|
||||
ch = job_channels[j];
|
||||
if (ch<0) return (-1);
|
||||
code[7] = rsuset (UUNAME);
|
||||
code[8] = jname;
|
||||
access (ch, 026);
|
||||
syswrite (ch, code, 9);
|
||||
piclr = ruset (ch, UPICLR);
|
||||
wuset (ch, UPICLR, 0);
|
||||
pirqc = ruset (ch, UPIRQ);
|
||||
wuset (ch, UAPIRQ, pirqc);
|
||||
pc = ruset (ch, UPC);
|
||||
wuset (ch, UPC, 026);
|
||||
j_start (j);
|
||||
sts = j_wait (j);
|
||||
job_status[j] = osts;
|
||||
if (sts == js_valret) sts = 0;
|
||||
else {wuset (ch, UAPIRQ, sts); sts = -1;}
|
||||
wuset (ch, UPC, pc);
|
||||
wuset (ch, UIPIRQ, pirqc);
|
||||
wuset (ch, UPICLR, piclr);
|
||||
return (sts);
|
||||
}
|
||||
|
||||
int j_flush (j)
|
||||
|
||||
{char *p;
|
||||
|
||||
job_channels[j] = -1;
|
||||
job_status[j] = js_nojob;
|
||||
job_name[j] = 0;
|
||||
if (p = job_jcl[j])
|
||||
{sfree (p);
|
||||
job_jcl[j] = 0;
|
||||
}
|
||||
if (p = job_valret[j])
|
||||
{sfree (p);
|
||||
job_valret[j] = 0;
|
||||
}
|
||||
on (inferior0_interrupt+j, 0);
|
||||
}
|
||||
|
||||
int j_give_tty (j)
|
||||
|
||||
{int ch, rc;
|
||||
|
||||
if (j<0 || j>=MAXJOBS) return (-1);
|
||||
ch = job_channels[j];
|
||||
if (ch<0) return (-1);
|
||||
rc = atty (ch);
|
||||
if (rc == 0) jobtty = j;
|
||||
return (rc);
|
||||
}
|
||||
|
||||
int j_take_tty (j)
|
||||
|
||||
{int ch, rc;
|
||||
|
||||
if (j<0 || j>=MAXJOBS) return (-1);
|
||||
ch = job_channels[j];
|
||||
if (ch<0) return (-1);
|
||||
rc = dtty (ch);
|
||||
if (rc == 0) jobtty = -1;
|
||||
return (rc);
|
||||
}
|
||||
|
||||
int j_grab_tty ()
|
||||
|
||||
{if (jobtty >= 0)
|
||||
{int rc;
|
||||
jobotty = jobtty;
|
||||
jobosts = job_status[jobtty];
|
||||
j_stop (jobtty);
|
||||
rc = j_take_tty (jobtty);
|
||||
if (rc && jobosts==0) j_start (jobtty);
|
||||
return (rc);
|
||||
}
|
||||
jobotty = -1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int j_retn_tty ()
|
||||
|
||||
{if (jobtty < 0 && jobotty >= 0)
|
||||
{j_give_tty (jobotty);
|
||||
if (jobosts == 0) j_start (jobotty);
|
||||
jobotty = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int j_wait (j)
|
||||
|
||||
{int sts;
|
||||
|
||||
if (j<0 || j>=MAXJOBS) return (-1);
|
||||
job_wait = j;
|
||||
sts = wfnz (&job_status[j]);
|
||||
job_wait = -1;
|
||||
return (sts);
|
||||
}
|
||||
|
||||
int j_onchange (f) int (*f)();
|
||||
|
||||
{jchandler = f;
|
||||
}
|
||||
|
||||
int j_sts (j)
|
||||
|
||||
{if (j<0 || j>=MAXJOBS) return (-1);
|
||||
return (job_status[j]);
|
||||
}
|
||||
|
||||
int j_sjcl (j, s) char *s;
|
||||
|
||||
{char *buf, *p;
|
||||
int ch, i;
|
||||
|
||||
if (j<0 || j>=MAXJOBS) return (-1);
|
||||
ch = job_channels[j];
|
||||
if (ch<0) return (-1);
|
||||
if (*s==0)
|
||||
{if (buf = job_jcl[j]) /* flush previous */
|
||||
{i = ruset (ch, UOPTION) & ~OPTCMD;
|
||||
wuset (ch, UOPTION, i);
|
||||
sfree (buf);
|
||||
job_jcl[j] = 0;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
i = salloc (slen (s) + 2);
|
||||
if (i <= 0) return (-1);
|
||||
buf = i;
|
||||
stcpy (s, buf);
|
||||
p = buf;
|
||||
while (*p) ++p;
|
||||
if (p==buf || p[-1]!='\r')
|
||||
{p[0] = '\r';
|
||||
p[1] = 0;
|
||||
}
|
||||
job_jcl[j] = buf;
|
||||
wuset (ch, UOPTION, OPTCMD);
|
||||
}
|
||||
|
||||
char *j_jcl (j)
|
||||
|
||||
{if (j<0 || j>=MAXJOBS) return (0);
|
||||
return (job_jcl[j]);
|
||||
}
|
||||
|
||||
int j_ch (j)
|
||||
|
||||
{if (j<0 || j>=MAXJOBS) return (-1);
|
||||
return (job_channels[j]);
|
||||
}
|
||||
|
||||
int j_name (j, f) filespec *f;
|
||||
|
||||
{f->dev = _USR;
|
||||
f->dir = 0;
|
||||
f->fn1 = runame();
|
||||
if (j>=0 && j<MAXJOBS)
|
||||
{f->fn2 = job_name[j];
|
||||
return (f->fn2 == 0);
|
||||
}
|
||||
f->fn2 = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
char *j_val (j)
|
||||
|
||||
{if (j<0 || j>=MAXJOBS) return (0);
|
||||
return (job_valret[j]);
|
||||
}
|
||||
|
||||
j_fval (j)
|
||||
|
||||
{if (j<0 || j>=MAXJOBS) return;
|
||||
if (job_valret[j] == 0) return;
|
||||
cfree (job_valret[j]);
|
||||
job_valret[j] = 0;
|
||||
}
|
||||
|
||||
j_handler (j)
|
||||
|
||||
{int ch, w, opt, old_status;
|
||||
|
||||
if (j<0 || j>=MAXJOBS) return;
|
||||
ch = job_channels[j];
|
||||
if (ch<0) return;
|
||||
|
||||
old_status = job_status[j];
|
||||
w = ruset (ch, UPIRQ);
|
||||
wuset (ch, UAPIRQ, PJTTY+PIIOC+PIARO+PICZ+PIVAL);
|
||||
opt = ruset (ch, UOPTION);
|
||||
if ((opt & OPTOPC)==0 && (w & IBACKUP))
|
||||
wuset (ch, UPC, ruset (ch, UPC) - 1);
|
||||
|
||||
job_status[j] = w;
|
||||
if (w & PICZ) /* ^Z typed */
|
||||
{job_status[j] = js_attn;
|
||||
return;
|
||||
}
|
||||
if (w & PIVAL) /* .VALUE */
|
||||
jdovalue (j);
|
||||
else if (w & PIBRK) /* .BREAK */
|
||||
jdobrk (j);
|
||||
|
||||
if (j != job_wait && job_status[j] != old_status && jchandler)
|
||||
(*jchandler)(j,job_status[j]);
|
||||
}
|
||||
|
||||
jdovalue (j) /* handle .VALUE */
|
||||
|
||||
{int ch, ich, cmda, n;
|
||||
char *p, buf[VALBUFSIZ];
|
||||
filespec f;
|
||||
|
||||
ch = job_channels[j];
|
||||
job_valret[j] = 0;
|
||||
job_status[j] = js_valret;
|
||||
cmda = ruset (ch, USV40) & 0777777;
|
||||
if (cmda == 0) return;
|
||||
if (j_name (j, &f)) return;
|
||||
if ((ich = open (&f, UII)) < 0) return;
|
||||
access (ich, cmda);
|
||||
n = VALBUFSIZ;
|
||||
p = buf;
|
||||
while (TRUE)
|
||||
{int w, i, c;
|
||||
w = uiiot (ich);
|
||||
for (i=0;i<5;++i)
|
||||
{c = (w>>29) & 0177;
|
||||
w =<< 7;
|
||||
if (c!='\n') {*p++ = c; --n;}
|
||||
if (c=='\r') {*p++ = '\n'; --n;}
|
||||
if (!c) break;
|
||||
if (n<=2)
|
||||
{*p++ = c = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!c) break;
|
||||
}
|
||||
close (ich);
|
||||
if (stcmp (buf, ":KILL\r") || stcmp (buf, ":KILL\r\n"))
|
||||
{/* if (job_wait != j) j_kill (j);
|
||||
else */ job_status[j] = js_suicide;
|
||||
return;
|
||||
}
|
||||
p = calloc (slen (buf) + 1);
|
||||
stcpy (buf, p);
|
||||
job_valret[j] = p;
|
||||
return;
|
||||
}
|
||||
|
||||
jdobrk (j) /* handle .BREAK */
|
||||
/* unless there is a 'fatal error', the job status
|
||||
must be changed to something reasonable */
|
||||
|
||||
{int ch, i;
|
||||
ch = job_channels[j];
|
||||
wuset (ch, UAPIRQ, PIBRK); /* reset PIRQ bit */
|
||||
i = ruset (ch, USV40); /* the instruction */
|
||||
if ((i & ~000740000000) == 042000000033)
|
||||
i = 045700160000; /* .LOGOUT n, */
|
||||
switch (i>>18) { /* opcode */
|
||||
|
||||
case 045700: /* .BREAK 16 */
|
||||
/* if ((i & 020000) && (job_wait != j)) j_kill (j);
|
||||
else */ job_status[j] = js_suicide;
|
||||
return;
|
||||
|
||||
case 045500: /* .BREAK 12 */
|
||||
jdob12 (j, i);
|
||||
return;
|
||||
}
|
||||
|
||||
j_start (j);
|
||||
}
|
||||
|
||||
jdob12 (j, i) /* handle .BREAK 12 */
|
||||
|
||||
{int cmda, ich, och;
|
||||
filespec f;
|
||||
|
||||
cmda = i & 0777777;
|
||||
if (j_name (j, &f)) return;
|
||||
if ((ich = open (&f, UII)) < 0) return;
|
||||
if ((och = open (&f, UIO)) < 0)
|
||||
{close (ich);
|
||||
return;
|
||||
}
|
||||
access (ich, cmda);
|
||||
i = uiiot (ich);
|
||||
if (i & 0200000000000) /* multiple commands */
|
||||
{int n, a;
|
||||
n = (i>>18) | 0777777000000;
|
||||
a = i & 0777777;
|
||||
while (n<0)
|
||||
{access (och, cmda);
|
||||
++n;
|
||||
++a;
|
||||
uoiot (och, (n<<18) | a);
|
||||
access (ich, a-1);
|
||||
do_brk (j, ich, och, uiiot (ich));
|
||||
}
|
||||
}
|
||||
else do_brk (j, ich, och, i);
|
||||
close (ich);
|
||||
close (och);
|
||||
j_start (j);
|
||||
}
|
||||
|
||||
do_brk (j, ich, och, w) /* do .BREAK 12 command W */
|
||||
|
||||
{int cmd, a, f, i;
|
||||
|
||||
cmd = (w>>18) & 0177777;
|
||||
a = w & 0777777;
|
||||
access (och, a);
|
||||
if (cmd==6) /* send :PRINT defaults */
|
||||
{uoiot (och, _DSK);
|
||||
uoiot (och, rsname ());
|
||||
uoiot (och, _FOO);
|
||||
uoiot (och, _GR);
|
||||
return;
|
||||
}
|
||||
if (cmd==5 && job_jcl[j])
|
||||
{f = copen (job_jcl[j], 'r', "s");
|
||||
access (ich, a+2);
|
||||
while (TRUE)
|
||||
{w = 0;
|
||||
for (i=0;i<5;++i) w = (w<<7) | (cgetc (f) & 0177);
|
||||
w =<< 1;
|
||||
uoiot (och, w);
|
||||
if ((w & 0377) == 0) break;
|
||||
if (uiiot (ich))
|
||||
{uoiot (och, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cclose (f);
|
||||
return;
|
||||
}
|
||||
if (cmd==10) /* send XJNAME */
|
||||
{uoiot (och, job_xname[j]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
57
src/clib/c10map.c
Normal file
57
src/clib/c10map.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
|
||||
FILMAP - file mapping routines
|
||||
|
||||
filmap (c, o, s) map in part of a file
|
||||
filunmap (p, s) unmap part of a file
|
||||
|
||||
*/
|
||||
|
||||
# include "c.defs"
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
FILMAP - map in a part of a disk file
|
||||
return a pointer to it
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int *filmap (ch, offset, size)
|
||||
|
||||
{int block_no, page_no, word_no, no_pages, i;
|
||||
int *p;
|
||||
|
||||
block_no = offset>>10;
|
||||
word_no = offset & 01777;
|
||||
no_pages = ((word_no + size - 1) >> 10) + 1;
|
||||
page_no = pg_get (no_pages);
|
||||
if (page_no < 0)
|
||||
{puts ("FILMAP: Unable to Allocate Pages.\n");
|
||||
return (0);
|
||||
}
|
||||
for (i=0;i<no_pages;++i)
|
||||
if (corblk (0600000, -1, page_no+i, ch, block_no+i))
|
||||
{cprint ("FILMAP: Error In Mapping Page %d.\n", block_no+i);
|
||||
break;
|
||||
}
|
||||
p = (page_no<<10)+word_no;
|
||||
return (p);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
FILUNMAP - Unmap pages mapped by FILMAP
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
filunmap (p, size) int *p;
|
||||
|
||||
{int page_no, word_no, no_pages, p_rep;
|
||||
|
||||
p_rep = p;
|
||||
word_no = p_rep & 01777;
|
||||
page_no = p_rep >> 10;
|
||||
no_pages = ((word_no + size - 1) >> 10) + 1;
|
||||
pg_ret (page_no, no_pages);
|
||||
}
|
||||
|
||||
489
src/clib/c10mio.cmid
Normal file
489
src/clib/c10mio.cmid
Normal file
@@ -0,0 +1,489 @@
|
||||
;
|
||||
; C10MIO - C I/O ROUTINES WRITTEN IN MIDAS
|
||||
;
|
||||
; This file is ITS dependent.
|
||||
;
|
||||
|
||||
TITLE MIO
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
; INCLUDES:
|
||||
;
|
||||
; CGETC - CIO GET CHARACTER
|
||||
; CPUTC - CIO PUT CHARACTER
|
||||
; CGETI - CIO GET INTEGER (IMAGE)
|
||||
; CPUTI - CIO PUT INTEGER (IMAGE)
|
||||
; CEOF - CIO TEST FOR END-OF-FILE
|
||||
; CFLUSH - CIO FLUSH BUFFER
|
||||
; REW - REWIND INPUT FILE
|
||||
; CLOSALL - CIO CLOSE ALL FILES
|
||||
; CCLOSE - CIO CLOSE FILE
|
||||
; ISTTY - IS FILE A TTY?
|
||||
; CISFD - IS PTR AN ACTUAL FILE DESCRIPTOR?
|
||||
; ITSCHAN - RETURN ACTUAL ITS CHANNEL
|
||||
;
|
||||
|
||||
; REGISTERS
|
||||
|
||||
FP==3 ; FILE CONTROL BLOCK POINTER
|
||||
T1==4 ; TEMPORARY
|
||||
|
||||
; VALUES
|
||||
|
||||
NL==12
|
||||
CR==15
|
||||
|
||||
; FILE CONTROL BLOCK ENTRIES
|
||||
|
||||
FBUFFP==0 ; (LEFT HALF) POINTER TO BUFFER (OR ZERO IF NOT BUFFERED)
|
||||
FCHAN: 160400,,(FP) ; ITS CHANNEL NUMBER
|
||||
FDEVIC: 100600,,(FP) ; DEVICE CODE
|
||||
FFLAG==0 ; (RIGHTMOST 8 BITS) FLAGS
|
||||
PHYEOF==1 ; PHYSICAL EOF REACHED (BUFFERED INPUT)
|
||||
%OPEN==2 ; FILE IS OPEN
|
||||
%WRITE==4 ; FILE IS OPEN FOR WRITE
|
||||
%TTY==10 ; FILE IS TTY
|
||||
%UNSET==20 ; DEVICE AND CHANNEL NOT SET YET
|
||||
FBPTR==1 ; POINTER TO NEXT CHAR/WORD OR CHAR/WORD POSITION
|
||||
FBCNT==2 ; NUMBER OF CHARS/WORDS OR AVAILABLE POSITIONS IN BUFFER
|
||||
FUCNT==3 ; (LEFT HALF) NUMBER OF CHARS IN UNGETC BUFFER
|
||||
FUPTR==3 ; (RIGHT HALF) POINTER TO UNGETC BUFFER
|
||||
FCLSR==4 ; (LEFT HALF) ADDRESS OF CLOSE ROUTINE
|
||||
FNGETR==4 ; (RIGHT HALF) ADDRESS OF NORMAL GETC ROUTINE
|
||||
FGETCR==5 ; ADDRESS OF CGETC ROUTINE
|
||||
FPUTCR==6 ; ADDRESS OF CPUTC ROUTINE
|
||||
FCBSIZ==7 ; SIZE OF FILE CONTROL BLOCK
|
||||
|
||||
; CONSTANTS
|
||||
|
||||
IBFSIZ==200
|
||||
NCHAN==10.
|
||||
UBFFSZ==20.
|
||||
|
||||
CENTRY CGETC,[FD]
|
||||
XENTRY GETC,CGETC
|
||||
XENTRY CGETI,CGETC
|
||||
XENTRY GETI,CGETC
|
||||
|
||||
HRRZ FP,FD ; FILE DESCRIPTOR
|
||||
GO @FGETCR(FP) ; JUMP TO APPROPRIATE ROUTINE
|
||||
|
||||
GETBUF: SOSGE FBCNT(FP) ; HERE FOR BUFFERED CHAR INPUT
|
||||
JSP B,GTBUF1 ; BUFFER EMPTY, GO FILL IT
|
||||
ILDB A,FBPTR(FP) ; GET NEXT CHAR FROM BUFFER
|
||||
CAIN A,CR ; IGNORE INCOMING CR
|
||||
GO GETBUF
|
||||
RETURN
|
||||
|
||||
GETBIN: SOSGE FBCNT(FP) ; HERE FOR BINARY INPUT
|
||||
GO GTBIN1 ; BUFFER EMPTY, REFILL IT
|
||||
MOVE A,@FBPTR(FP) ; GET NEXT WORD FROM BUFFER
|
||||
AOS FBPTR(FP) ; INCR POINTER
|
||||
RETURN
|
||||
|
||||
GETSTR: MOVE A,@FBPTR(FP) ; HERE FOR STRING INPUT
|
||||
AOS FBPTR(FP) ; INCR POINTER
|
||||
JUMPE A,NEWEOF
|
||||
RETURN
|
||||
|
||||
GETTTY: CALL TYI ; HERE FOR TTY INPUT
|
||||
HRRZ FP,FD ; RESTORE FP
|
||||
JUMPE A,NEWEOF
|
||||
RETURN
|
||||
|
||||
IENTRY GC$BAD
|
||||
CROAK BAD CALL TO CGETC/CGETI
|
||||
SETO A,
|
||||
RETURN
|
||||
|
||||
GETUN: HLRZ B,FUCNT(FP) ; HERE WHEN CHAR IN UNGETC BUFFER
|
||||
JUMPLE B,CODE [ ; IS UNGETC BUFFER EMPTY?
|
||||
HRRZ A,FNGETR(FP) ; YES
|
||||
MOVEM A,FGETCR(FP) ; RESTORE CGETC ROUTINE
|
||||
GO (A) ; GET NEXT CHAR
|
||||
]
|
||||
HRRZ A,FUPTR(FP)
|
||||
ADD A,B
|
||||
HRRZ A,(A) ; GET CHAR
|
||||
SUBI B,1 ; DECR COUNT
|
||||
HRLM B,FUCNT(FP)
|
||||
RETURN
|
||||
|
||||
NEWEOF: MOVEI A,EOF ; HERE ON NEWLY DISCOVERED EOF
|
||||
MOVEM A,FGETCR(FP)
|
||||
HRRM A,FNGETR(FP) ; SET CGETC ROUTINE TO EOF
|
||||
EOF: SETZ A,
|
||||
RETURN
|
||||
|
||||
; BUFFERED CHARACTER INPUT - BUFFER READ ROUTINE
|
||||
;
|
||||
; CONTAINS HACKERY WHICH ALLOWS DETECTION OF LAST WORD
|
||||
; OF FILE. TRAILING CONTROL-C'S ARE REMOVED FROM THIS
|
||||
; WORD. CALLED VIA JSP B,
|
||||
;
|
||||
|
||||
GTBUF1: HRRZ T1,FFLAG(FP) ; HERE TO FILL OR REFILL BUFFER
|
||||
TRNE T1,PHYEOF ; HAS END OF FILE BEEN REACHED?
|
||||
GO NEWEOF ; YES, ANNOUNCE IT
|
||||
MOVN A,FBCNT(FP) ; OLD CHARACTER COUNT (CHECKED LATER)
|
||||
MOVEI T1,5*<IBFSIZ-1> ; RESET CHARACTER COUNT
|
||||
MOVEM T1,FBCNT(FP) ; (LAST WORD SAVED FOR NEXT BUFFER)
|
||||
HLRZ T1,FBUFFP(FP) ; RESET CHARACTER POINTER
|
||||
HRLI T1,440700 ; TO BEGINNING OF BUFFER
|
||||
MOVEM T1,FBPTR(FP)
|
||||
CAIE A,2 ; CHECK OLD COUNT FOR SPECIAL VALUE
|
||||
GO GTBUF2 ; NORMAL (NOT INIT) CASE
|
||||
HLRZ T1,FBUFFP(FP) ; FIRST TIME - FILL ENTIRE BUFFER
|
||||
HRLI T1,-IBFSIZ
|
||||
GO GTBUF3
|
||||
|
||||
GTBUF2: HLRZ T1,FBUFFP(FP) ; NORMAL CASE - ONE WORD SAVED FROM LAST READ
|
||||
MOVE A,IBFSIZ-1(T1) ; GET LAST WORD OF BUFFER (UNREAD)
|
||||
MOVEM A,(T1) ; MAKE FIRST WORD OF BUFFER
|
||||
ADDI T1,1 ; ADJUST CPTR TO FILL REST OF BUFFER
|
||||
HRLI T1,-IBFSIZ+1
|
||||
|
||||
GTBUF3: LDB A,FCHAN ; ITS CHANNEL NUMBER
|
||||
LSH A,23.
|
||||
IOR A,[.IOT T1]
|
||||
XCT A ; EXECUTE .IOT
|
||||
JUMPGE T1,-2(B) ; BUFFER WAS FILLED, NO MORE TO DO
|
||||
HLRES T1
|
||||
ADDI T1,IBFSIZ ; NUMBER OF WORDS READ
|
||||
HLRZ A,FBUFFP(FP)
|
||||
ADDI A,-1(T1) ; POINTER TO WORD LAST READ
|
||||
IMULI T1,5 ; NUMBER OF CHARS READ
|
||||
PPUSH B
|
||||
MOVEI B,5 ; CHECK FOR AT MOST 5 TRAILING ^C'S
|
||||
HRLI A,010700 ; BYTE POINTER TO LAST CHAR
|
||||
GTBUF4: LDB 0,A ; GRAB CHARACTER
|
||||
ADD A,[070000,,0] ; DECREMENT BYTE POINTER
|
||||
CAIE 0,3 ; IS IT A ^C
|
||||
GO GTBUF5 ; NO
|
||||
SUBI T1,1 ; DECREMENT CHARACTER COUNT
|
||||
SOJG B,GTBUF4 ; KEEP LOOKING
|
||||
GTBUF5: PPOP B
|
||||
MOVEM T1,FBCNT(FP) ; SET CHARACTER COUNT
|
||||
MOVEI T1,PHYEOF
|
||||
IORM T1,FFLAG(FP) ; SET PHYSICAL EOF FLAG
|
||||
GO -2(B) ; THAT'S IT!
|
||||
|
||||
;
|
||||
; GTBIN1 - INTERNAL CODE FOR BINARY BUFFER GET
|
||||
;
|
||||
GTBIN1: HRRZ T1,FFLAG(FP) ; HERE TO REFILL BUFFER IN BINARY MODE
|
||||
TRNE T1,PHYEOF ; HAS END OF FILE BEEN REACHED?
|
||||
GO NEWEOF ; YES, ANNOUNCE IT
|
||||
MOVEI T1,IBFSIZ
|
||||
MOVEM T1,FBCNT(FP) ; RESET COUNTER
|
||||
HLRZ T1,FBUFFP(FP) ; BUFFER POINTER
|
||||
MOVEM T1,FBPTR(FP) ; RESET POINTER
|
||||
HRLI T1,-IBFSIZ ; COUNTING POINTER FOR IOT
|
||||
LDB A,FCHAN
|
||||
LSH A,23.
|
||||
IOR A,[.IOT T1] ; SET UP .IOT INSTRUCTION
|
||||
XCT A ; EXECUTE .IOT INSTRUCTION
|
||||
JUMPGE T1,GETBIN ; BUFFER WAS FILLED, RESUME
|
||||
HLRES T1
|
||||
ADDI T1,IBFSIZ ; NUMBER OF WORDS ACTUALLY READ
|
||||
MOVEM T1,FBCNT(FP) ; SET COUNTER
|
||||
MOVEI T1,PHYEOF
|
||||
IORM T1,FFLAG(FP) ; SET PHYSICAL EOF FLAG
|
||||
GO GETBIN ; RESUME
|
||||
|
||||
CENTRY CPUTC,[CC,FD]
|
||||
XENTRY PUTC,CPUTC
|
||||
XENTRY CPUTI,CPUTC
|
||||
XENTRY PUTI,CPUTC
|
||||
|
||||
HRRZ FP,FD ; FILE DESCRIPTOR
|
||||
MOVE A,CC ; CHARACTER (OR INTEGER) TO BE WRITTEN
|
||||
GO @FPUTCR(FP) ; JUMP TO APPROPRIATE ROUTINE
|
||||
|
||||
PUTBUF: CAIN A,NL ; HERE FOR BUFFERED CHAR OUTPUT
|
||||
GO CODE [
|
||||
CALL CPUTC,[[[CR]],FP]
|
||||
HRRZ FP,FD
|
||||
MOVEI A,NL
|
||||
GO PF$1
|
||||
]
|
||||
JUMPE A,PC$RET ; DONT WRITE NULLS
|
||||
PF$1: IDPB A,FBPTR(FP) ; STORE CHAR
|
||||
SOSG FBCNT(FP) ; BUFFER FULL?
|
||||
GO CODE [ ; YES
|
||||
MCALL FLUSHB,[FP,[[IBFSIZ]]] ; FLUSH ENTIRE BUFFER
|
||||
GO PC$RET
|
||||
]
|
||||
PC$RET: RETURN ; NO, RETURN
|
||||
|
||||
PUTBIN: MOVEM A,@FBPTR(FP) ; HERE ON BINARY OUTPUT
|
||||
AOS FBPTR(FP)
|
||||
SOSLE FBCNT(FP)
|
||||
GO PC$RET
|
||||
HLRZ T1,FBUFFP(FP)
|
||||
HRLI T1,-IBFSIZ ; SET UP COUNTING POINTER FOR .IOT
|
||||
LDB A,FCHAN ; GET ITS CHANNEL NUMBER
|
||||
LSH A,23.
|
||||
IOR A,[.IOT T1] ; PREPARE .IOT INSTRUCTION
|
||||
XCT A ; EXECUTE .IOT INSTRUCTION
|
||||
MOVEI T1,IBFSIZ
|
||||
MOVEM T1,FBCNT(FP) ; RESET COUNTER
|
||||
HLRZ T1,FBUFFP(FP)
|
||||
MOVEM T1,FBPTR(FP) ; RESET POINTER
|
||||
GO PC$RET
|
||||
|
||||
PUTSTR: MOVEM A,@FBPTR(FP) ; HERE ON STRING OUTPUT
|
||||
AOS FBPTR(FP)
|
||||
GO PC$RET
|
||||
|
||||
PUTTTY: CAIN A,NL ; HERE ON TTY OUTPUT
|
||||
MOVEI A,CR ; OUTPUT NEWLINES AS CR'S
|
||||
CALL TYO,[A]
|
||||
GO PC$RET
|
||||
|
||||
IENTRY PC$BAD
|
||||
CROAK BAD CALL TO CPUTC/CPUTI
|
||||
SETO A,
|
||||
GO PC$RET
|
||||
|
||||
CENTRY CEOF,[FD]
|
||||
|
||||
HRRZ FP,FD
|
||||
SETZ A,
|
||||
HRRZ B,FGETCR(FP)
|
||||
CAIN B,EOF
|
||||
MOVEI A,1
|
||||
CAIN B,GC$BAD
|
||||
SETO A,
|
||||
RETURN
|
||||
|
||||
CENTRY UNGETC,[CC,FD]
|
||||
|
||||
HRRZ FP,FD ; FILE DESCRIPTOR
|
||||
MOVE A,CC ; CHARACTER
|
||||
HLRZ T1,FUCNT(FP) ; NUMBER OF CHARS IN BUFFER
|
||||
ADDI T1,1
|
||||
CAIL T1,UBFFSZ ; TOO MANY?
|
||||
GO CODE [
|
||||
SETO A,
|
||||
GO UN$RET
|
||||
]
|
||||
HRLM T1,FUCNT(FP)
|
||||
HRRZ B,FUPTR(FP)
|
||||
ADD T1,B
|
||||
MOVEM A,(T1) ; STORE CHAR
|
||||
MOVEI B,GETUN
|
||||
MOVEM B,FGETCR(FP) ; SET UP GETC ROUTINE
|
||||
UN$RET: RETURN
|
||||
|
||||
CENTRY CFLUSH,[FD]
|
||||
|
||||
MCALL FLUSHP,[FD,[[0]]]
|
||||
RETURN
|
||||
|
||||
MENTRY FLUSHP,[FD,PADC]
|
||||
|
||||
HRRZ FP,FD
|
||||
HRRZ A,FPUTCR(FP) ; OUTPUT ROUTINE
|
||||
CAIE A,PUTBUF
|
||||
GO FL$RET
|
||||
HRRZ T1,PADC ; PAD CHARACTER
|
||||
MOVEI A,5*IBFSIZ ; NUMBER OF CHAR POSITIONS
|
||||
SUB A,FBCNT(FP) ; NUMBER OF ACTUAL CHARS IN BUFFER
|
||||
JUMPLE A,FL$RET ; BUFFER IS EMPTY
|
||||
IDIVI A,5
|
||||
JUMPE B,FL$1 ; NO PARTIALLY FILLED WORDS
|
||||
MOVN B,B
|
||||
ADDI B,5
|
||||
IDPB T1,FBPTR(FP) ; FILL OUT WITH ^C'S
|
||||
SOJG B,.-1
|
||||
ADDI A,1
|
||||
FL$1: MCALL FLUSHB,[FP,A]
|
||||
FL$RET: RETURN
|
||||
|
||||
MENTRY FLUSHB,[FD,SIZE]
|
||||
|
||||
MOVE FP,FD ; FILE POINTER
|
||||
MOVN T1,SIZE ; SIZE OF FILLED PART OF BUFFER
|
||||
HRLZ T1,T1 ; CONSTRUCT
|
||||
HLR T1,FBUFFP(FP) ; .IOT POINTER
|
||||
LDB B,FCHAN
|
||||
LSH B,23.
|
||||
IOR B,[.IOT T1] ; PREPARE .IOT INSTRUCTION
|
||||
XCT B ; EXECUTE .IOT INSTRUCTION
|
||||
MOVEI T1,5*IBFSIZ
|
||||
MOVEM T1,FBCNT(FP) ; RESET COUNTER
|
||||
HLRZ T1,FBUFFP(FP)
|
||||
HRLI T1,440700
|
||||
MOVEM T1,FBPTR(FP) ; RESET ABPTR
|
||||
RETURN
|
||||
|
||||
CENTRY REW,[FD]
|
||||
|
||||
HRRZ FP,FD
|
||||
SETOM FBCNT(FP)
|
||||
HRRZ A,FFLAG(FP)
|
||||
TRZ A,PHYEOF
|
||||
HRRM A,FFLAG(FP)
|
||||
MOVE A,GETTAB+1
|
||||
MOVEM A,FGETCR(FP)
|
||||
LDB A,FCHAN
|
||||
.CALL [SETZ ? 'ACCESS ? A ? 401000,,0]
|
||||
CROAK REW: ACCESS FAILED
|
||||
RETURN
|
||||
|
||||
CENTRY CLOSALL,,[COUNTER] ; CLOSE ALL C FILES
|
||||
|
||||
MOVEI A,NCHAN-1
|
||||
MOVEM A,COUNTER
|
||||
MOVE A,COUNTER
|
||||
CA$1: CALL CCLOSE,[FCBTBL(A)]
|
||||
SOSL A,COUNTER
|
||||
GO CA$1
|
||||
RETURN
|
||||
|
||||
CENTRY CCLOSE,[FD]
|
||||
|
||||
HRRZ FP,FD
|
||||
HLRZ A,FCLSR(FP)
|
||||
GO (A) ; JUMP TO APPROPRIATE ROUTINE
|
||||
|
||||
CLOBUF: MCALL FLUSHP,[FP,[[3]]]
|
||||
GO CLIBUF
|
||||
|
||||
CLOBIN: MOVE A,FBCNT(FP) ; HERE ON BINARY OUTPUT
|
||||
SUBI A,IBFSIZ
|
||||
JUMPGE A,CLIBUF
|
||||
HRLZ A,A
|
||||
HLR A,FBUFFP(FP)
|
||||
LDB B,FCHAN
|
||||
LSH B,23.
|
||||
IOR B,[.IOT A]
|
||||
XCT B ; FLUSH BUFFER
|
||||
|
||||
CLIBUF: LDB A,FCHAN ; HERE ON BUFFERED AND BINARY INPUT
|
||||
; ALSO FALL THROUGH FROM BUFFERED AND BINARY OUTPUT
|
||||
CALL MCLOSE,[A]
|
||||
MOVE FP,FD
|
||||
|
||||
CLTTY: SETZ A, ; HERE ON TTY AND FALL THROUGH
|
||||
|
||||
CLOSE2: MOVEI T1,%OPEN ; HERE TO CLEAR %OPEN BIT
|
||||
ANDCAM T1,FFLAG(FP)
|
||||
MOVEI T1,GC$BAD ; SET ROUTINES TO BAD
|
||||
MOVEM T1,FGETCR(FP)
|
||||
MOVEI T1,PC$BAD
|
||||
MOVEM T1,FPUTCR(FP)
|
||||
MOVE T1,[CL$BAD,,GC$BAD]
|
||||
MOVEM T1,FCLSR(FP)
|
||||
CL$RET: RETURN
|
||||
|
||||
CLOSTR: MOVE A,FBPTR(FP) ; HERE ON STRING OUTPUT
|
||||
SETZM (A) ; APPEND NULL ONTO STRING
|
||||
GO CLOSE2 ; RETURN POINTER TO NULL CHAR
|
||||
|
||||
IENTRY CL$BAD
|
||||
SETO A,
|
||||
GO CL$RET
|
||||
|
||||
CENTRY ISTTY,[FD]
|
||||
|
||||
HRRZ FP,FD
|
||||
HRRZ A,FFLAG(FP)
|
||||
TRNE A,%UNSET ; IS DEVICE CODE VALID?
|
||||
GO IS$RET ; NO -- MUST BE A TTY
|
||||
LDB A,FDEVICE ; GET IT
|
||||
CAILE A,2 ; TEST FOR TTY DEVICES
|
||||
SETZ A,
|
||||
IS$RET: RETURN
|
||||
|
||||
; INTERNAL ROUTINE TO SET DEVICE AND CHANNEL
|
||||
; MUST BE THE TTY INPUT OR OUTPUT CHANNEL
|
||||
; RETURN DEVICE CODE
|
||||
|
||||
MENTRY SETDEV,[FD]
|
||||
|
||||
HRRZ FP,FD
|
||||
MOVE A,FFLAG(FP)
|
||||
TRNE A,%WRITE
|
||||
MOVEI B,ZTYOOPN"
|
||||
TRNN A,%WRITE
|
||||
MOVEI B,ZTYIOPN"
|
||||
VCALL (B)
|
||||
JUMPL A,SD$RET ; VALID CHANNEL RETURNED?
|
||||
HRRZ FP,FD
|
||||
DPB A,FCHAN ; YES - STORE IT
|
||||
LSH A,23.
|
||||
IOR A,[.STATUS A]
|
||||
XCT A
|
||||
ANDI A,77 ; GET DEVICE FROM CHANNEL STATUS
|
||||
DPB A,FDEVIC ; STORE DEVICE
|
||||
MOVEI T1,%UNSET ; CLEAR %UNSET BIT
|
||||
ANDCAM T1,FFLAG(FP)
|
||||
SD$RET: RETURN
|
||||
|
||||
CENTRY CISFD,[FD]
|
||||
|
||||
MOVE A,FD
|
||||
CAIGE A,C0FCBS+1
|
||||
GO ISF$NO
|
||||
CAIL A,C0FCBS+1+NCHAN*FCBSIZ
|
||||
GO ISF$NO
|
||||
MOVEI A,1
|
||||
RETURN
|
||||
ISF$NO: SETZ A,
|
||||
RETURN
|
||||
|
||||
CENTRY ITSCHAN,[FD]
|
||||
|
||||
HRRZ FP,FD
|
||||
HRRZ A,FFLAG(FP)
|
||||
TRNN A,%UNSET ; IS CHANNEL CODE VALID?
|
||||
GO IC$1 ; YES - GET IT
|
||||
MCALL SETDEV,[FD] ; NO -- SET IT AND RETURN IT
|
||||
RETURN
|
||||
IC$1: LDB A,FCHAN ; GET CHANNEL
|
||||
RETURN
|
||||
|
||||
.PDATA
|
||||
MDATA GETTAB
|
||||
GETTTY
|
||||
GETBUF
|
||||
GETBIN
|
||||
GETSTR
|
||||
GC$BAD
|
||||
GC$BAD
|
||||
GC$BAD
|
||||
GC$BAD
|
||||
|
||||
MDATA PUTTAB
|
||||
PC$BAD
|
||||
PC$BAD
|
||||
PC$BAD
|
||||
PC$BAD
|
||||
PUTTTY
|
||||
PUTBUF
|
||||
PUTBIN
|
||||
PUTSTR
|
||||
|
||||
MDATA CLOTAB
|
||||
CLTTY
|
||||
CLIBUF
|
||||
CLIBUF
|
||||
CLTTY
|
||||
CLTTY
|
||||
CLOBUF
|
||||
CLOBIN
|
||||
CLOSTR
|
||||
|
||||
; STATIC DATA AREAS
|
||||
|
||||
.UDATA
|
||||
MDATA C0FCBS
|
||||
BLOCK NCHAN*FCBSIZ+1
|
||||
|
||||
MDATA FCBTBL
|
||||
REPEAT NCHAN C0FCBS+1+.RPCNT*FCBSIZ
|
||||
|
||||
END
|
||||
110
src/clib/c10pag.c
Normal file
110
src/clib/c10pag.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* C PAGE Handling Package
|
||||
*
|
||||
* routines:
|
||||
*
|
||||
* pg = pg_get (n)
|
||||
* rc = pg_ret (pg, n)
|
||||
* b = pg_exist (pg)
|
||||
* i = pg_nshare (pg)
|
||||
* i = pp_nshare (p)
|
||||
*
|
||||
*/
|
||||
|
||||
# include "c.defs"
|
||||
|
||||
# rename page_table "PAGTAB"
|
||||
# rename first_free_page "FFPAGE"
|
||||
|
||||
int first_free_page;
|
||||
extern int page_table [256];
|
||||
extern int cerr;
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PG_GET - Page Get
|
||||
|
||||
Allocate "n" contiguous unused pages in the address space.
|
||||
Return the number of the lowest page allocated, or -1
|
||||
if unable to allocate pages.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int pg_get (n)
|
||||
|
||||
{int page, i, top, tp, n_free;
|
||||
|
||||
if (n<1 || n>254) return (-1);
|
||||
page = first_free_page; /* first page we examine */
|
||||
top = 256-n; /* highest possible low page */
|
||||
n_free = 0; /* number of free pages we see */
|
||||
while (page <= top)
|
||||
{for (i=0;i<n;++i)
|
||||
{tp = page+i;
|
||||
if (page_table[tp]!=0 || pg_exist(tp)) break;
|
||||
else ++n_free;
|
||||
}
|
||||
if (i>=n) break; /* success */
|
||||
page =+ i+1;
|
||||
}
|
||||
if (page > top) return (-1);
|
||||
for (i=0;i<n;++i) page_table[page+i] = -1;
|
||||
if (n_free==n) first_free_page = page+n;
|
||||
return (page);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PG_RET - Page Return
|
||||
|
||||
deallocate "n" pages in the address space and unmap them
|
||||
return non-zero on error
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int pg_ret (page, n)
|
||||
|
||||
{if (n<1 || page<=0 || page+n>256)
|
||||
{cprint (cerr, "PG_RET: invalid page number %d.\n", page);
|
||||
return (-1);
|
||||
}
|
||||
if (page < first_free_page) first_free_page = page;
|
||||
while (--n >= 0)
|
||||
{page_table[page] = 0;
|
||||
corblk (0, -1, page, -1, page);
|
||||
++page;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PG_EXIST - Does page exist in address space?
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
pg_exist (page_no)
|
||||
|
||||
{int blk[4];
|
||||
|
||||
cortyp (page_no, blk);
|
||||
return (page_table[page_no] = (blk[0] != 0));
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PG_NSHARE - Return number of times page is shared
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
pp_nshare (p) {return (pg_nshare (p>>10));}
|
||||
|
||||
pg_nshare (page_no)
|
||||
|
||||
{int blk[4];
|
||||
|
||||
cortyp (page_no, blk);
|
||||
return (blk[3] & 0777777);
|
||||
}
|
||||
|
||||
430
src/clib/c10run.cmid
Normal file
430
src/clib/c10run.cmid
Normal file
@@ -0,0 +1,430 @@
|
||||
;
|
||||
; C10RUN - BASIC C RUN-TIME SUPPORT
|
||||
;
|
||||
; This file is ITS dependent.
|
||||
;
|
||||
|
||||
TITLE CRUN
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
.GLOBAL A,B,C,D,P,GO,.CCALL,.VCALL,.ACALL,.XCALL
|
||||
|
||||
PDLSIZ==20000 ; DESIRED PDL SIZE
|
||||
MAXARG==40. ; MAXIMUM NUMBER OF ARGUMENTS
|
||||
BUFSZ==250. ; COMMAND BUFFER SIZE IN CHARACTERS
|
||||
TP==16
|
||||
|
||||
;
|
||||
; START-UP ROUTINE
|
||||
;
|
||||
|
||||
IENTRY START
|
||||
|
||||
; ENABLE INTERRUPTS
|
||||
|
||||
.SUSET [.ROPTI,,A] ; READ OPTION WORD
|
||||
TLO A,OPTOPC+OPTINT ; SET OLD PC ON MPV, IOC AND
|
||||
; USE NEW INTERRUPT STACKING SCHEME
|
||||
.SUSET [.SOPTI,,A] ; SET OPTION WORD
|
||||
|
||||
MOVE A,[-TSINTL",,TSINT"] ; SET UP INTERRUPT HANDLING
|
||||
MOVEM A,42
|
||||
MOVEI A,%PIMPV+%PIPDL ; ENABLE MPV AND PDL OVERFLOW
|
||||
.SUSET [.SMASK,,A]
|
||||
|
||||
;SET UP UUO HANDLER
|
||||
|
||||
MOVE A,[JSR UUOH"]
|
||||
MOVEM A,41
|
||||
|
||||
MOVE P,PDLBOT ; STACK
|
||||
MOVE TP,TPINIT ; TIME STACK (IF IN TIMING MODE)
|
||||
MCALL $SETUP
|
||||
IENTRY RESTART
|
||||
MOVE P,PDLBOT
|
||||
VCALL @CALLER,[ARGC,[[ARGV]]]
|
||||
CALL CEXIT,[[[0]]]
|
||||
IENTRY .EXIT
|
||||
SETZM TIMING
|
||||
SKIPE EXITER
|
||||
VCALL @EXITER ; CLEAN-UP TIMING
|
||||
.LOGOUT ; IN CASE WE ARE AT TOP LEVEL
|
||||
.BREAK 16,160000 ; COMMIT SUICIDE
|
||||
|
||||
; SETUP ROUTINE
|
||||
|
||||
; TURN OFF TTY ECHOING, READ AND PARSE JCL COMMAND,
|
||||
; GET JOB NAME, INITIALIZE I/O, OPEN TTY
|
||||
|
||||
MENTRY $SETUP
|
||||
|
||||
; TURN OFF TTY ECHOING
|
||||
|
||||
.SUSET [.RTTY,,A] ; READ TTY WORD
|
||||
TLNE A,400000 ; TEST %TBNOT BIT
|
||||
GO SET$0 ; DONT HAVE TTY
|
||||
.OPEN 17,[SIXBIT/ TTY/]
|
||||
GO SET$0 ; WHO CARES IF IT FAILS
|
||||
.CALL [SETZ ; TURN OFF ECHOING
|
||||
'TTYSET
|
||||
1000,,17
|
||||
[020202020202]
|
||||
SETZ [030202020202]
|
||||
]
|
||||
JFCL
|
||||
.CLOSE 17,
|
||||
|
||||
SET$0: .CLOSE 1, ; HACK FOR TOP-LEVEL BOOTSTRAP
|
||||
.CLOSE 2,
|
||||
.CLOSE 3,
|
||||
|
||||
; READ JCL
|
||||
|
||||
.SUSET [.ROPTI,,A] ; READ OPTION WORD
|
||||
TLNN A,OPTCMD ; IS THERE SOME JCL
|
||||
GO SET$2 ; NOPE
|
||||
|
||||
SETZM JCLBUF ; FIRST WORD -- MAKE SURE ITS THERE
|
||||
SETOM JCLBUF+<BUFSZ/5>-1 ; LAST WORD OF JCLBUF
|
||||
.BREAK 12,[..RJCL,,JCLBUF] ; READ JCL
|
||||
|
||||
; READ JOB NAME
|
||||
|
||||
SET$2: .SUSET [.RXJNAME,,XJNAME]
|
||||
|
||||
; PARSE JCL
|
||||
|
||||
MCALL PRSARG,[[[440700,,JCLBUF]],[[ARGBUF]],[[ARGV]],XJNAME,[[MAXARG]]]
|
||||
MOVEM A,ARGC
|
||||
|
||||
CALL C0INIT ; INITIALIZE C I/O ROUTINES
|
||||
CALL FXARG,[ARGC,[[ARGV]]] ; DO REDIRECTION OF STANDARD I/O
|
||||
MOVEM A,ARGC
|
||||
|
||||
.SUSET [.RTTY,,A] ; READ TTY WORD
|
||||
TLNE A,400000 ; TEST %TBNOT BIT
|
||||
GO SET$R ; RETURN IF DONT HAVE TTY
|
||||
CALL TYIOPN ; ENABLE INTERRUPT CHARS
|
||||
SET$R: RETURN
|
||||
|
||||
IENTRY STKDMP
|
||||
|
||||
PUSH P,0 ; SAVE REGISTERS
|
||||
PUSH P,A
|
||||
PUSH P,B
|
||||
PUSH P,C
|
||||
PUSH P,D
|
||||
PUSH P,[0] ; PLACE TO SAVE 'REAL' RETURN ADDRESS
|
||||
PUSH P,[0] ; ZERO ARG TO STKDMP
|
||||
.VALUE [ASCIZ\..XECP/0/1Q
|
||||
P\]
|
||||
MOVEM 0,-1(P) ; SAVE AWAY 'REAL' RETURN ADDRESS
|
||||
PUSHJ P,ZSTKDMP"
|
||||
POP P,(P)
|
||||
POP P,D
|
||||
POP P,C
|
||||
POP P,B
|
||||
POP P,A
|
||||
POP P,0
|
||||
POPJ P,
|
||||
|
||||
;
|
||||
; EXIT ROUTINES
|
||||
;
|
||||
|
||||
CENTRY CEXIT,[CC]
|
||||
CALL CLOSALL
|
||||
MOVE A,CC
|
||||
GO .EXIT
|
||||
|
||||
CENTRY CQUIT,[CC]
|
||||
CROAK CQUIT CALLED
|
||||
CALL CEXIT,[CC]
|
||||
|
||||
|
||||
; CODE TO PERFORM LOAD-TIME INITIALIZATION
|
||||
; FLUSHES ZERO PAGES IN IMPURE AREAS
|
||||
|
||||
.IDATA
|
||||
; NO LITERALS IN THIS CODE!
|
||||
|
||||
IENTRY LBINIT ; INIT FOR MAKING LIBRARY
|
||||
SETZM IFLUSH ; DON'T FLUSH ZERO-PAGES BECAUSE
|
||||
; MAKLIB EXPECTS THEM TO BE THERE
|
||||
MOVE A,LBD1 ; RESET FLUSH-FLAG WHEN DONE
|
||||
MOVEM A,IDONE
|
||||
GO LINIT
|
||||
LBD1: SETOM IFLUSH
|
||||
|
||||
IENTRY LINIT
|
||||
|
||||
MOVEI P,ARGV ; TEMPORARY PDL
|
||||
|
||||
IENTRY ISTART
|
||||
|
||||
JFCL
|
||||
|
||||
; SETUP SEGMENT BOUNDARIES
|
||||
|
||||
HLRZ A,20
|
||||
MOVEM A,SEG0LO
|
||||
HRRZ A,20
|
||||
MOVEM A,SEG0HI
|
||||
SETZM 20
|
||||
HLRZ A,21
|
||||
MOVEM A,SEG1LO
|
||||
HRRZ A,21
|
||||
MOVEM A,SEG1HI
|
||||
SETZM 21
|
||||
HLRZ A,22
|
||||
MOVEM A,SEG2LO
|
||||
HRRZ A,22
|
||||
MOVEM A,SEG2HI
|
||||
SETZM 22
|
||||
HLRZ A,23
|
||||
MOVEM A,SEG3LO
|
||||
HRRZ A,23
|
||||
MOVEM A,SEG3HI
|
||||
SETZM 23
|
||||
|
||||
; INITIALIZE PAGE-TABLE
|
||||
|
||||
MOVEI A,256.
|
||||
I$LOOP: SOJL A,I$SMSH ; A IS PAGE NUMBER
|
||||
.CALL I$CORT ; GET PAGE INFO
|
||||
.VALUE I$MES1 ; SYSTEM CALL LOST
|
||||
MOVEM B,PAGTAB(A)
|
||||
GO I$LOOP
|
||||
|
||||
; NOW LOOK FOR .CCALLS TO SMASH
|
||||
|
||||
I$SMSH: SKIPE TIMING ; DON'T SMASH IF TIMING
|
||||
GO I$FLSH
|
||||
SKIPA A,SEG2LO ; POINTER TO BEGINNING OF CODE AREA
|
||||
I$S1: ADDI A,1 ; NEXT WORD
|
||||
CAML A,SEG2HI ; AT END OF CODE AREA?
|
||||
GO I$PURE ; DONE
|
||||
HLRZ B,(A) ; INSTRUCTION
|
||||
TRZ B,000777 ; ISOLATE OPCODE
|
||||
CAIE B,(.CCALL) ; IS IT A .CCALL?
|
||||
GO I$S1 ; NO, GO ON
|
||||
HLRZ B,(A) ; THE INSTRUCTION AGAIN
|
||||
TRNN B,000037 ; IS INDEXING OR INDIRECTION USED
|
||||
GO I$S6 ; NO, IT'S A CONSTANT CALL
|
||||
TRZ B,777000 ; SMASH OPCODE
|
||||
IORI B,(.VCALL) ; MAKE IT A .VCALL
|
||||
HRLM B,(A) ; SMASH THE .CCALL
|
||||
GO I$S1 ; GO ON TO NEXT WORD
|
||||
|
||||
I$S6: HRRZ C,(A) ; THE CALLED PROCEDURE
|
||||
JUMPE C,I$S1 ; NO SUCH PROCEDURE
|
||||
HLRZ 0,-1(C) ; THE NUMBER OF FORMAL ARGS
|
||||
CAIL 0,20 ; REASONABLE NUMBER?
|
||||
GO I$S1 ; NO, NOT A PROCEDURE
|
||||
LDB B,[270400,,(A)] ; THE NUMBER OF ACTUAL ARGS
|
||||
CAIE 0,(B) ; DO THE NUMBERS MATCH?
|
||||
GO I$S2 ; NO
|
||||
MOVEI B,(PUSHJ P,)
|
||||
HRLM B,(A) ; SMASH .CCALL TO PUSHJ
|
||||
GO I$S1
|
||||
|
||||
; HERE IF NUMBER OF ACTUALS AND FORMALS ARE DIFFERENT
|
||||
|
||||
I$S2: SUBI 0,(B) ; NUMBER OF EXTRA ACTUALS NEEDED
|
||||
JUMPL 0,I$S5 ; TOO MANY ACTUALS GIVEN
|
||||
MOVE B,0
|
||||
ADDI B,2
|
||||
CL I$ALLC ; ALLOCATE SPACE FOR PROG
|
||||
HRRZ B,D ; ADDRESS OF BLOCK
|
||||
HRLI B,(JSP D,) ; CONSTRUCT CALL TO IT
|
||||
MOVEM B,(A) ; SMASH ORIGINAL CALL
|
||||
SUBI D,1
|
||||
I$S3: SOJL 0,I$S4 ; FOR EACH MISSING ARG
|
||||
PUSH D,PZERO ; COMPILE A PUSH OF ZERO
|
||||
GO I$S3
|
||||
I$S4: PUSH D,PUSHD ; COMPILE A PUSH OF D (RETURN ADDRESS)
|
||||
HRLI C,(GO) ; MAKE JUMP TO CALLED PROC
|
||||
PUSH D,C ; COMPILE CALL
|
||||
GO I$S1 ; FINISHED WITH THIS CALL
|
||||
|
||||
; HERE IF NUMBER OF ACTUALS EXCEEDS NUMBER OF FORMALS
|
||||
|
||||
I$S5: MOVEI B,3 ; GET TWO WORDS
|
||||
CL I$ALLC
|
||||
HRRZ B,D ; ADDRESS OF BLOCK
|
||||
HRLI B,(JSP D,) ; MAKE CALL TO IT
|
||||
MOVEM B,(A) ; SMASH ORIGINAL CALL
|
||||
MOVN B,0 ; NUMBER OF EXTRA ARGS
|
||||
HRLI B,(SUBI P,) ; CONSTRUCT INSTRUCTION
|
||||
MOVEM B,(D) ; STORE IN BLOCK
|
||||
MOVE B,PUSHD
|
||||
MOVEM B,1(D)
|
||||
HRLI C,(GO) ; MAKE JUMP TO CALLED PROC
|
||||
MOVEM C,2(D) ; STORE IN BLOCK
|
||||
GO I$S1 ; FINISHED WITH THIS CALL
|
||||
|
||||
; NOW PURIFY HIGH SEGMENTS
|
||||
|
||||
I$PURE: MOVE A,SEG2LO
|
||||
TRZ A,1777
|
||||
MOVE B,SEG2HI
|
||||
SUBI B,(A)
|
||||
LSH A,-10.
|
||||
ADDI B,1777
|
||||
LSH B,-10.
|
||||
MOVN B,B
|
||||
HRL A,B
|
||||
.CALL I$PBLK
|
||||
.VALUE I$MES4
|
||||
MOVE A,SEG3LO
|
||||
TRZ A,1777
|
||||
MOVE B,SEG3HI
|
||||
SUBI B,(A)
|
||||
LSH A,-10.
|
||||
ADDI B,1777
|
||||
LSH B,-10.
|
||||
MOVN B,B
|
||||
HRL A,B
|
||||
.CALL I$PBLK
|
||||
.VALUE I$MES4
|
||||
|
||||
; NOW LOOK FOR ZERO-PAGES TO FLUSH
|
||||
|
||||
I$FLSH: SKIPN IFLUSH
|
||||
GO I$DONE
|
||||
MOVEI A,0 ; FIRST PAGE IS 1 (CAN'T FLUSH 0!)
|
||||
NXTPAG: ADDI A,1 ; CURRENT PAGE NUMBER
|
||||
MOVE B,A
|
||||
LSH B,10. ; POINTER TO FIRST WORD IN PAGE
|
||||
CAMLE B,SEG1HI ; STILL IN IMPURE AREA?
|
||||
GO I$DONE ; NO, DONE
|
||||
SKIPN PAGTAB(A) ; DOES PAGE EXIST?
|
||||
GO NXTPAG ; NO, TRY NEXT ONE
|
||||
NXTWRD: SKIPE (B) ; IS THE WORD ZERO
|
||||
GO NXTPAG ; NO, CAN'T FLUSH THIS PAGE
|
||||
ADDI B,1 ; NEXT WORD
|
||||
TRNE B,1777 ; IN NEXT PAGE?
|
||||
GO NXTWRD ; NO, KEEP GOING
|
||||
.CALL I$CORB ; YES, DELETE PAGE
|
||||
.VALUE I$MES2 ; SYSTEM CALL LOST
|
||||
GO NXTPAG ; GO ON TO NEXT PAGE
|
||||
|
||||
I$DONE:
|
||||
|
||||
IENTRY IDONE
|
||||
|
||||
JFCL
|
||||
SETZ A, ; CLEAN UP
|
||||
SETZ B, ; LIKE A GOOD BOY SHOULD
|
||||
SETZ C,
|
||||
SETZ D,
|
||||
.BREAK 16,0 ; RETURN TO LOADER
|
||||
|
||||
; STORAGE ALLOCATOR FOR .CCALL COMPILER
|
||||
; CALL WITH SIZE IN B
|
||||
; RETURNS ADDRESS IN D
|
||||
|
||||
I$ALLC: MOVE D,SEG3HI ; TOP OF PATCH SPACE
|
||||
ADDI D,1 ; POINT TO NEW BLOCK
|
||||
ADDB B,SEG3HI ; NEW TOP OF PATCH SPACE
|
||||
LSH B,-10. ; PAGE OF TOP OF PATCH SPACE
|
||||
SKIPE PAGTAB(B) ; DOES PAGE EXIST?
|
||||
RTN ; YES
|
||||
.CALL I$GETB ; GET PAGE
|
||||
.VALUE I$MES3 ; SYSTEM CALL LOST
|
||||
SETOM PAGTAB(B) ; UPDATE PAGE TABLE
|
||||
RTN ; RETURN
|
||||
|
||||
MDATA TIMING
|
||||
0
|
||||
|
||||
IFLUSH: -1 ; FLUSH ZERO PAGES
|
||||
I$CORT: SETZ ? 'CORTYP ? A ? 402000,,B
|
||||
I$CORB: SETZ ? 'CORBLK ? 1000,,0 ? 1000,,%JSELF ? SETZ A
|
||||
I$PBLK: SETZ ? 'CORBLK ? 1000,,%CBNDR ? 1000,,%JSELF ? 400000,,A
|
||||
I$GETB: SETZ ? 'CORBLK ? 1000,,%CBNDR+%CBNDW ? 1000,,%JSELF ?
|
||||
B ? 401000,,%JSNEW
|
||||
I$MES1: ASCIZ/CORTYP FAILED/
|
||||
I$MES2: ASCIZ/PAGE-DELETE FAILED/
|
||||
I$MES3: ASCIZ/PAGE-GET FAILED/
|
||||
I$MES4: ASCIZ/PURIFY FAILED/
|
||||
|
||||
.CODE
|
||||
|
||||
IENTRY FIXIFY
|
||||
|
||||
JUMPL A,FIXL
|
||||
FADR A,[.499999]
|
||||
UFA A,[233000000000']
|
||||
TLZ B,777000'
|
||||
JRST @0
|
||||
FIXL: MOVN A,A
|
||||
FADR A,[.499999]
|
||||
UFA A,[233000000000']
|
||||
TLZ B,777000'
|
||||
MOVN B,B
|
||||
JRST @0
|
||||
|
||||
; IMPURE AREA
|
||||
|
||||
.IDATA
|
||||
-1 ; THIS STUFF MUST NOT BE FLUSHED!
|
||||
MDATA PAGTAB ; PAGE TABLE
|
||||
BLOCK 256.
|
||||
MDATA ARGV
|
||||
BLOCK MAXARG ; POINTERS TO ARGS PLACED HERE
|
||||
MDATA XJNAME
|
||||
BLOCK 1 ; JOB NAME
|
||||
MDATA SEG0LO
|
||||
0
|
||||
MDATA SEG0HI
|
||||
0
|
||||
MDATA SEG1LO
|
||||
0
|
||||
MDATA SEG1HI
|
||||
0
|
||||
MDATA SEG2LO
|
||||
0
|
||||
MDATA SEG2HI
|
||||
0
|
||||
MDATA SEG3LO
|
||||
0
|
||||
MDATA SEG3HI
|
||||
0
|
||||
; END OF WIRED-DOWN STUFF (PROTECTED
|
||||
; ON THIS END BY CALLER)
|
||||
MDATA CALLER
|
||||
ZMAIN" ; C ROUTINE CALLED AS PROGRAM
|
||||
MDATA PURBOT
|
||||
0
|
||||
MDATA PURTOP
|
||||
0
|
||||
|
||||
.UDATA
|
||||
MDATA EXITER
|
||||
BLOCK 1 ; EXIT ROUTINE (FOR TIMING)
|
||||
ARGC: BLOCK 1 ; NUMBER OF ARGUMENTS TO MAIN
|
||||
JCLBUF: BLOCK BUFSZ/5 ; JCL BUFFER
|
||||
ARGBUF: BLOCK BUFSZ ; MAIN ARGS BUFFER
|
||||
PDL: BLOCK PDLSIZ ; THE STACK
|
||||
.IDATA
|
||||
MDATA PDLBOT
|
||||
PDL
|
||||
MDATA PDLTOP
|
||||
PDL+PDLSIZ-1
|
||||
.PDATA
|
||||
MDATA PZERO
|
||||
PUSH P,ZERO
|
||||
MDATA ZERO
|
||||
0
|
||||
MDATA PUSHD
|
||||
PUSH P,D
|
||||
MDATA TPINIT ; SET BY TINIT
|
||||
0
|
||||
|
||||
CONSTANTS
|
||||
|
||||
MDATA PATCH
|
||||
|
||||
END START
|
||||
43
src/clib/c10sav.cmid
Normal file
43
src/clib/c10sav.cmid
Normal file
@@ -0,0 +1,43 @@
|
||||
;
|
||||
; CSAVE - Routine to prepare for saving a program file
|
||||
;
|
||||
; This file is ITS dependent.
|
||||
; This file contains the size of the shared library file.
|
||||
;
|
||||
|
||||
TITLE CSAVE
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
.GLOBAL TYICHN,TYOCHN,PDLBOT,PDLTOP
|
||||
|
||||
CENTRY CSAVE
|
||||
|
||||
SETOM TYICHN
|
||||
SETOM TYOCHN
|
||||
MOVE A,[-10.,,246.]
|
||||
.CALL [SETZ ? 'CORBLK ? MOVEI 0 ? MOVEI %JSELF ? SETZ A]
|
||||
; DELETE SHARED LIBRARY PAGES
|
||||
CROAK CORBLK FAILED
|
||||
|
||||
; DELETE STACK PAGES
|
||||
|
||||
MOVE A,PDLBOT
|
||||
ADDI A,1777
|
||||
TRZ A,1777 ; MOVE TO NEXT PAGE BOUNDARY
|
||||
MOVE B,PDLTOP ; LAST WORD OF STACK
|
||||
ADDI B,1
|
||||
TRZ B,1777 ; MOVE TO PREVIOUS PAGE BOUNDARY
|
||||
LSH A,-10.
|
||||
LSH B,-10. ; GET PAGE NUMBERS
|
||||
SUB B,A ; NUMBER OF PAGES
|
||||
MOVN B,B ; NEGATIVE NUMBER OF PAGES
|
||||
HRL A,B ; MAKE COUNTING POINTER
|
||||
|
||||
.CALL [SETZ ? 'CORBLK ? MOVEI 0 ? MOVEI %JSELF ? SETZ A]
|
||||
CROAK CORBLK FAILED
|
||||
|
||||
.VALUE [ASCIZ/:PDUMP /]
|
||||
RETURN
|
||||
|
||||
END
|
||||
24
src/clib/c10sfd.c
Normal file
24
src/clib/c10sfd.c
Normal file
@@ -0,0 +1,24 @@
|
||||
/**********************************************************************
|
||||
|
||||
SETFDIR - Set File Directory (and defaults)
|
||||
(obsolete)
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
char *setfdir (buf, name, dir)
|
||||
char *buf, *name, *dir;
|
||||
|
||||
{filespec fs1, fs2;
|
||||
char *p;
|
||||
|
||||
fparse (name, &fs1);
|
||||
fparse (dir, &fs2);
|
||||
if (fs2.dir==0) fs2.dir=fs2.fn1;
|
||||
if (fs2.dev) fs1.dev = fs2.dev;
|
||||
else if (fs1.dev==0) fs1.dev=csto6("dsk");
|
||||
if (fs2.dir) fs1.dir = fs2.dir;
|
||||
else if (fs1.dir==0) fs1.dir=rsname();
|
||||
p = prfile (&fs1, buf);
|
||||
*p = 0;
|
||||
return (buf);
|
||||
}
|
||||
63
src/clib/c10sry.cmid
Normal file
63
src/clib/c10sry.cmid
Normal file
@@ -0,0 +1,63 @@
|
||||
;
|
||||
; C10SRY - CHANGE .VCALL'S TO PUSHJ'S
|
||||
;
|
||||
; This file is ITS dependent.
|
||||
; This routine assumes a superior DDT.
|
||||
;
|
||||
|
||||
TITLE SORRY
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
.GLOBAL SEG2LO,SEG2HI,SEG3LO,SEG3HI
|
||||
|
||||
IENTRY SORRY
|
||||
|
||||
.VALUE [ASCIZ/:UNPURE
|
||||
P/]
|
||||
|
||||
; MOVE A,SEG2LO
|
||||
; TRZ A,1777
|
||||
; MOVE B,SEG2HI
|
||||
; SUBI B,(A)
|
||||
; LSH A,-10.
|
||||
; ADDI B,1777
|
||||
; LSH B,-10.
|
||||
; MOVN B,B
|
||||
; HRL A,B
|
||||
; .CALL I$IMPR
|
||||
; .VALUE
|
||||
|
||||
SKIPA A,SEG2LO ; POINTER TO BEGINNING OF CODE AREA
|
||||
S1: ADDI A,1 ; NEXT WORD
|
||||
CAML A,SEG2HI ; AT END OF CODE AREA?
|
||||
GO DONE
|
||||
HLRZ B,(A) ; INSTRUCTION
|
||||
TRZ B,000777 ; ISOLATE OPCODE
|
||||
CAIE B,(.VCALL) ; IS IT A .CCALL?
|
||||
GO S1 ; NO, GO ON
|
||||
HLRZ B,(A) ; THE INSTRUCTION AGAIN
|
||||
TRZ B,777740 ; FLUSH OPCODE AND ACCUMULATOR
|
||||
IORI B,(PUSHJ P,) ; MAKE IT A PUSHJ
|
||||
HRLM B,(A) ; STORE IT
|
||||
GO S1
|
||||
|
||||
DONE: MOVE A,SEG2LO
|
||||
TRZ A,1777
|
||||
MOVE B,SEG3HI
|
||||
SUBI B,(A)
|
||||
LSH A,-10.
|
||||
ADDI B,1777
|
||||
LSH B,-10.
|
||||
MOVN B,B
|
||||
HRL A,B
|
||||
.CALL I$PURE
|
||||
.VALUE
|
||||
|
||||
.VALUE [ASCIZ/:PDUMP /]
|
||||
.BREAK 16,0
|
||||
|
||||
.PDATA
|
||||
I$PURE: SETZ ? 'CORBLK ? 1000,,%CBNDR ? 1000,,%JSELF ? 400000,,A
|
||||
;I$IMPR: SETZ ? 'CORBLK ? 1000,,%CBRED+%CBWRT ? 1000,,%JSELF ? 400000,,A
|
||||
END
|
||||
135
src/clib/c10std.c
Normal file
135
src/clib/c10std.c
Normal file
@@ -0,0 +1,135 @@
|
||||
# include "c.defs"
|
||||
# include "stdio.h"
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
STDIO.C - 'Standard I/O' Simulator for ITS
|
||||
|
||||
Must call STDIO to initialize.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int *stdin, *stdout, *stderr;
|
||||
extern int cin, cout, cerr;
|
||||
|
||||
stdio ()
|
||||
|
||||
{stdin = cin; stdout = cout; stderr = cerr;
|
||||
on (ctrlg_interrupt, INT_IGNORE);
|
||||
}
|
||||
|
||||
flopen (name, mode)
|
||||
char *name, *mode;
|
||||
|
||||
{int f;
|
||||
f = copen (name, mode[0]);
|
||||
if (f == OPENLOSS) return (0);
|
||||
return (f);
|
||||
}
|
||||
|
||||
int fgetc (f)
|
||||
|
||||
{int c;
|
||||
c = cgetc (f);
|
||||
if (c < 0) return (EOF);
|
||||
if (c == 0 && ceof (f)) return (EOF);
|
||||
return (c);
|
||||
}
|
||||
|
||||
int fgeth ()
|
||||
|
||||
{return (fgetc (cin));}
|
||||
|
||||
int peekc (f)
|
||||
|
||||
{int c;
|
||||
c = cgetc (f);
|
||||
if (c < 0) return (EOF);
|
||||
if (c == 0 && ceof (f)) return (EOF);
|
||||
ungetc (c, f);
|
||||
return (c);
|
||||
}
|
||||
|
||||
int pkchar ()
|
||||
|
||||
{return (peekc (cin));}
|
||||
|
||||
printf (a, b, c, d, e, f, g)
|
||||
{cprint (cout, a, b, c, d, e, f, g);}
|
||||
|
||||
fprintf (a, b, c, d, e, f, g)
|
||||
{cprint (a, b, c, d, e, f, g);}
|
||||
|
||||
fclose (f) {cclose (f);}
|
||||
|
||||
fread (f, buf, size, number) char buf[];
|
||||
|
||||
{int n;
|
||||
n = size * number;
|
||||
while (--n >= 0) *buf++ = cgetc (f);
|
||||
}
|
||||
|
||||
freopen (name, mode, f) char *name, *mode;
|
||||
|
||||
{int i;
|
||||
cclose (f);
|
||||
i = copen (name, *mode);
|
||||
return (i);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
STRING ROUTINES
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
strcmp (s1, s2)
|
||||
char *s1, *s2;
|
||||
|
||||
{int c1, c2;
|
||||
while (TRUE)
|
||||
{c1 = *s1++;
|
||||
c2 = *s2++;
|
||||
if (c1 < c2) return (-1);
|
||||
if (c1 > c2) return (1);
|
||||
if (c1 == 0) return (0);
|
||||
}
|
||||
}
|
||||
|
||||
strcpy (dest, source)
|
||||
char *dest, *source;
|
||||
|
||||
{stcpy (source, dest);}
|
||||
|
||||
strcat (dest, source)
|
||||
char *dest, *source;
|
||||
|
||||
{while (*dest) ++dest;
|
||||
stcpy (source, dest);
|
||||
}
|
||||
|
||||
getuid () {return (rsuset (074));}
|
||||
|
||||
getpw (w, buf) char *buf;
|
||||
{c6tos (w, buf);}
|
||||
|
||||
nowtime (tv) int tv[];
|
||||
{cal foo;
|
||||
now (&foo);
|
||||
tv[0] = tv[1] = cal2f (&foo);
|
||||
}
|
||||
|
||||
char *ctime (tv) int tv[];
|
||||
{static char buf[100];
|
||||
cal foo;
|
||||
int f;
|
||||
f2cal (tv[0], &foo);
|
||||
f = copen (buf, 'w', "s");
|
||||
prcal (&foo, f);
|
||||
cputc ('\n', f);
|
||||
cclose (f);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
unlink (s) {delete (s);}
|
||||
exit (cc) {cexit (cc);}
|
||||
727
src/clib/c10sys.cmid
Normal file
727
src/clib/c10sys.cmid
Normal file
@@ -0,0 +1,727 @@
|
||||
;
|
||||
; C10SYS - C LIBRARY ROUTINES (INTERFACES TO SYSTEM CALLS)
|
||||
;
|
||||
; This file is ITS dependent.
|
||||
;
|
||||
|
||||
TITLE C10SYS
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
; CONTAINS:
|
||||
|
||||
; SYSOPEN ; OPEN CHANNEL
|
||||
; CLOSE ; CLOSE CHANNEL
|
||||
; CHNLOC ; FIND AVAILABLE CHANNEL
|
||||
|
||||
; UIIOT ; PERFORM UNIT INPUT IOT
|
||||
; UOIOT ; PERFORM UNIT OUTPUT IOT
|
||||
; SYSREAD ; PERFORM BLOCK INPUT IOT
|
||||
; SYSWRITE ; PERFORM BLOCK OUTPUT IOT
|
||||
; SIOT ; STRING IOT
|
||||
|
||||
; SYSFINISH ; FORCE OUTPUT AND WAIT FOR COMPLETION
|
||||
; SYSFORCE ; FORCE OUTPUT TO DEVICE
|
||||
|
||||
; RESET ; RESET CHANNEL
|
||||
; STATUS ; GET CHANNEL STATUS
|
||||
; RFPNTR ; READ FILE ACCESS POINTER
|
||||
; ACCESS ; PERFORM RANDOM ACCESS ON CHANNEL
|
||||
; FILLEN ; GET FILE LENGTH
|
||||
; FILNAM ; GET FILE NAME FROM CHANNEL
|
||||
|
||||
; RAUTH ; READ FILE AUTHOR
|
||||
; SAUTH ; SET FILE AUTHOR
|
||||
; RDMPBT ; READ DUMP BIT
|
||||
; SDMPBT ; SET DUMP BIT
|
||||
; SREAPB ; SET DO-NOT-REAP BIT
|
||||
; RFDATE ; READ FILE CREATION DATE
|
||||
; SFDATE ; SET FILE CREATION DATE
|
||||
; SRDATE ; SET FILE REFERENCE DATE
|
||||
; DSKUPD ; UPDATE FILE INFO
|
||||
; RESRDT ; RESTORE FILE INFO
|
||||
|
||||
; TTYGET ; GET TTY STATUS
|
||||
; TTYSET ; SET TTY STATUS
|
||||
; CNSGET ; GET CONSOLE PARAMETERS
|
||||
; CNSSET ; SET CONSOLE PARAMETERS
|
||||
|
||||
; ITYIC ; READ TTY INTERRUPT CHARACTER
|
||||
; WHYINT ; WHY WAS I INTERRUPTED?
|
||||
; SYSLISTEN ; LISTEN FOR TTY INPUT
|
||||
; RCPOS ; READ CURSOR POSITION
|
||||
; SCML ; SET # OF COMMAND LINES
|
||||
|
||||
; GETCPU ; RETURN CPU TIME IN 4.069 USEC
|
||||
; CPUTM ; RETURN CPU TIME IN 1/60 SECONDS
|
||||
; SLEEP ; GO TO SLEEP
|
||||
; ETIME ; RETURN A TIME FOR ELAPSED TIME MEASUREMENT
|
||||
; NOW ; GET CURRENT DATE AND TIME
|
||||
|
||||
; CORBLK ; PERFORM PAGE HACKING
|
||||
; CORTYP ; GET INFORMATION ABOUT PAGE
|
||||
; PAGEID ; GET NAMED PUBLIC PAGE
|
||||
; PGWRIT ; CAUSE PAGE TO BE WRITTEN ON DISK
|
||||
|
||||
; RSNAME ; READ SNAME
|
||||
; SSNAME ; SET SNAME
|
||||
; RUNAME ; READ USER NAME
|
||||
; RSUSET ; WHAT = RSUSET (WHERE)
|
||||
; WSUSET ; WHAT = WSUSET (WHERE, WHAT)
|
||||
; RUSET ; WHAT = RUSET (WHO, WHERE)
|
||||
; WUSET ; WHAT = WUSET (WHO, WHERE, WHAT)
|
||||
; WUSRVAR ; RC = WUSRVAR (JOB, SPEC, VALUE)
|
||||
|
||||
; DELETE ; DELETE A FILE
|
||||
; SYSDEL ; DELETE FILE
|
||||
; RENMWO ; RENAME FILE OPEN FOR OUTPUT
|
||||
; SYSRNM ; EC = SYSRNM (FS1, FS2)
|
||||
; SYSLNK ; EC = MAKE LINK (FS1, FS2)
|
||||
; DIRSIZ ; READ DIRECTORY SIZE, QUOTA INFO
|
||||
|
||||
; TRANAD ; RC = TRANAD (JOB, FROM, TO, FLAGS)
|
||||
; TRANCL ; RC = TRANCL (JOB, FLAGS)
|
||||
; TRANDL ; RC = TRANDL (JOB, FILESPEC, FLAGS)
|
||||
|
||||
; SYSLOAD ; LOAD A PROGRAM
|
||||
; PDUMP ; PDUMP A PROGRAM
|
||||
; UCLOSE ; DESTROY INFERIOR JOB
|
||||
; SYSDISOWN ; EC = SYSDISOWN (JOBCH)
|
||||
; REOWN ; EC = REOWN (JOBCH)
|
||||
; SYSDTACH ; EC = SYSDTACH (JOBCH)
|
||||
; SYSATACH ; EC = SYSATACH (JOBCH, TTY)
|
||||
|
||||
; ATTY ; GIVE TTY TO INFERIOR
|
||||
; DTTY ; TAKE TTY FROM INFERIOR
|
||||
|
||||
; WFNZ ; WAIT FOR WORD TO BECOME NON-ZERO
|
||||
; WFZ ; WAIT FOR WORD TO BECOME ZERO
|
||||
; VAL7RET ; VALRET AN ASCIZ STRING
|
||||
; DEMSIG ; SIGNAL A DEMON PROCESS
|
||||
; SSTATUS ; OBTAIN SYSTEM STATUS
|
||||
|
||||
; MAKTAG ; CREATE A TAG (GLOBAL LABEL)
|
||||
; GOTAG ; GOTO A TAG, DISMISSING INTERRUPTS
|
||||
|
||||
CENTRY SYSOPEN,[CHAN, FILSPC, MODE] ; OPEN CHANNEL
|
||||
|
||||
HRLZ B,MODE
|
||||
HRR B,CHAN
|
||||
HRRZ C,FILSPC
|
||||
SYSCAL OPEN,[B ? (C) ? 1(C) ? 2(C) ? 3(C)]
|
||||
RETURN
|
||||
|
||||
CENTRY CLOSE,[CHAN] ; CLOSE CHANNEL
|
||||
|
||||
SYSCAL CLOSE,[CHAN]
|
||||
RETURN
|
||||
|
||||
CENTRY CHNLOC ; FIND AVAILABLE CHANNEL
|
||||
|
||||
FIRSTC==1 ; CHANGE TO 0 IF SYSTEM FIXED SO THAT
|
||||
; CHANNEL 0 IS NOT ARBITRARILY SMASHED
|
||||
; BY .CALL MLINK, ETC.
|
||||
|
||||
MOVEI B,FIRSTC
|
||||
CL$1: SYSCAL RFNAME,[B ? 2000,,C]
|
||||
JUMPE C,CL$2 ; CHANNEL NOT OPEN
|
||||
ADDI B,1
|
||||
CAIGE B,20
|
||||
GO CL$1
|
||||
SETO A,
|
||||
GO CL$RET
|
||||
CL$2: MOVE A,B
|
||||
CL$RET: RETURN
|
||||
|
||||
CENTRY UIIOT,[CHAN] ; PERFORM UNIT INPUT IOT
|
||||
|
||||
MOVE A,CHAN
|
||||
ANDI A,17
|
||||
LSH A,23.
|
||||
IOR A,[.IOT A]
|
||||
XCT A
|
||||
RETURN
|
||||
|
||||
CENTRY UOIOT,[CHAN,DATA] ; PERFORM UNIT OUTPUT IOT
|
||||
|
||||
MOVE A,CHAN
|
||||
ANDI A,17
|
||||
LSH A,23.
|
||||
IOR A,[.IOT DATA]
|
||||
XCT A
|
||||
MOVE A,DATA
|
||||
RETURN
|
||||
|
||||
CENTRY SYSREAD,[CHAN,BUFFP,NWORDS] ; PERFORM BLOCK INPUT IOT
|
||||
XENTRY SYSWRITE,SYSREAD ; PERFORM BLOCK OUTPUT IOT
|
||||
|
||||
MOVN A,NWORDS ; MINUS NUMBER OF WORDS
|
||||
HRLZ 0,A
|
||||
HRR 0,BUFFP ; SET UP CPTR
|
||||
MOVE C,CHAN
|
||||
ANDI C,17
|
||||
LSH C,23.
|
||||
IOR C,[.IOT 0]
|
||||
XCT C
|
||||
HLRE C,0 ; NEW COUNTER
|
||||
SUB C,A ; NUMBER OF WORDS WRITTEN/READ
|
||||
MOVE A,C
|
||||
RETURN
|
||||
|
||||
CENTRY SIOT,[CHAN,BYTP,NBYTES] ; STRING IOT
|
||||
|
||||
SYSCAL SIOT,[CHAN ? BYTP ? NBYTES],SI$LOS
|
||||
MOVE A,NBYTES
|
||||
SI$RET: RETURN
|
||||
SI$LOS: CROAK SIOT LOST
|
||||
GO SI$RET
|
||||
|
||||
CENTRY SYSFINISH,[CHAN]
|
||||
|
||||
SYSCAL FINISH,[CHAN]
|
||||
RETURN
|
||||
|
||||
CENTRY SYSFORCE,[CHAN]
|
||||
|
||||
SYSCAL FORCE,[CHAN]
|
||||
RETURN
|
||||
|
||||
CENTRY RESET,[CHAN] ; RESET CHANNEL
|
||||
|
||||
MOVE A,CHAN
|
||||
ANDI A,17
|
||||
LSH A,23.
|
||||
IOR A,[.RESET]
|
||||
XCT A
|
||||
SETZ A,
|
||||
RETURN
|
||||
|
||||
CENTRY STATUS,[CHAN] ; GET CHANNEL STATUS
|
||||
|
||||
MOVE A,CHAN
|
||||
LSH A,23.
|
||||
IOR A,[.STATUS A]
|
||||
XCT A
|
||||
RETURN
|
||||
|
||||
CENTRY RFPNTR,[CHAN] ; READ FILE ACCESS POINTER
|
||||
|
||||
SYSCAL RFPNTR,[CHAN ? MOVEM B],RP$LOS
|
||||
MOVE A,B
|
||||
RP$RET: RETURN
|
||||
RP$LOS: MOVN A,A
|
||||
GO RP$RET
|
||||
|
||||
CENTRY ACCESS,[CHAN,POS] ; PERFORM RANDOM ACCESS ON CHANNEL
|
||||
|
||||
SYSCAL ACCESS,[CHAN ? POS]
|
||||
RETURN
|
||||
|
||||
CENTRY FILLEN,[CHAN] ; GET FILE LENGTH
|
||||
|
||||
SYSCAL FILLEN,[CHAN ? 2000,,B],FL$LOS
|
||||
MOVE A,B
|
||||
FL$RET: RETURN
|
||||
FL$LOS: MOVN A,A
|
||||
GO FL$RET
|
||||
|
||||
CENTRY FILNAM,[CHAN,FILSPC] ; GET FILE NAME FROM CHANNEL
|
||||
|
||||
HRLZ B,CHAN ; CHANNEL
|
||||
HRR B,FILSPC ; FILESPEC FOR RESULTS
|
||||
MOVE C,4(B) ; SAVE 5TH WORD
|
||||
.RCHST B, ; READ CHANNEL STATUS
|
||||
HRLZS (B) ; LEFT ADJUST DEV
|
||||
MOVEM C,4(B) ; RESTORE 5TH WORD
|
||||
RETURN ; DONE
|
||||
|
||||
CENTRY RAUTH,[CHAN]
|
||||
|
||||
SYSCAL RAUTH,[CHAN ? MOVEM B],RA$LOS
|
||||
MOVE A,B
|
||||
RA$RET: RETURN
|
||||
RA$LOS: MOVN A,A
|
||||
GO RA$RET
|
||||
|
||||
CENTRY SAUTH,[CHAN,AUTHOR]
|
||||
|
||||
SYSCAL SAUTH,[CHAN ? AUTHOR]
|
||||
RETURN
|
||||
|
||||
CENTRY RDMPBT,[CHAN]
|
||||
|
||||
SYSCAL RDMPBT,[CHAN ? MOVEM B],RD$LOS
|
||||
MOVE A,B
|
||||
RD$RET: RETURN
|
||||
RD$LOS: MOVN A,A
|
||||
GO RD$RET
|
||||
|
||||
CENTRY SDMPBT,[CHAN,BIT]
|
||||
|
||||
SYSCAL SDMPBT,[CHAN ? BIT]
|
||||
RETURN
|
||||
|
||||
CENTRY SREAPB,[CHAN,BIT]
|
||||
|
||||
SYSCAL SREAPB,[CHAN ? BIT]
|
||||
RETURN
|
||||
|
||||
CENTRY RFDATE,[CHAN] ; READ FILE CREATION DATE
|
||||
|
||||
SYSCAL RFDATE,[CHAN ? 2000,,B],RF$LOS
|
||||
MOVE A,B
|
||||
RF$RET: RETURN
|
||||
RF$LOS: MOVN A,A
|
||||
GO RF$RET
|
||||
|
||||
CENTRY SFDATE,[CHAN,FDATE] ; SET FILE CREATION DATE
|
||||
|
||||
SYSCAL SFDATE,[CHAN ? FDATE]
|
||||
RETURN
|
||||
|
||||
CENTRY SRDATE,[CHAN,FDATE] ; SET FILE REFERENCE DATE
|
||||
|
||||
SYSCAL SRDATE,[CHAN ? FDATE]
|
||||
RETURN
|
||||
|
||||
CENTRY DSKUPD,[CHAN]
|
||||
|
||||
SYSCAL DSKUPD,[CHAN]
|
||||
RETURN
|
||||
|
||||
CENTRY RESRDT,[CHAN]
|
||||
|
||||
SYSCAL RESRDT,[CHAN]
|
||||
RETURN
|
||||
|
||||
CENTRY TTYGET,[CHAN,BLOCK] ; GET TTY STATUS - WRITES 3 VALUES
|
||||
|
||||
HRRZ B,BLOCK
|
||||
SYSCAL TTYGET,[CHAN ? MOVEM (B) ? MOVEM 1(B) ? MOVEM 2(B)]
|
||||
RETURN
|
||||
|
||||
CENTRY TTYSET,[CHAN,BLOCK] ; SET TTY STATUS - READS 3 VALUES
|
||||
|
||||
HRRZ B,BLOCK
|
||||
SYSCAL TTYSET,[CHAN ? (B) ? 1(B) ? 2(B)]
|
||||
RETURN
|
||||
|
||||
CENTRY CNSGET,[CHAN,BLOCK] ; GET CONSOLE STATUS - WRITES 5 VALUES
|
||||
|
||||
HRRZ B,BLOCK
|
||||
SYSCAL CNSGET,[CHAN ? MOVEM (B) ? MOVEM 1(B) ? MOVEM 2(B)
|
||||
MOVEM 3(B) ? MOVEM 4(B)]
|
||||
RETURN
|
||||
|
||||
CENTRY CNSSET,[CHAN,BLOCK] ; SET CONSOLE STATUS - READS 5 VALUES
|
||||
|
||||
HRRZ B,BLOCK
|
||||
SYSCAL CNSSET,[CHAN ? (B) ? 1(B) ? 2(B) ? 3(B) ? 4(B)]
|
||||
RETURN
|
||||
|
||||
CENTRY WHYINT,[CHAN,BLOCK]
|
||||
|
||||
HRRZ B,BLOCK
|
||||
SYSCAL WHYINT,[CHAN ? (B) ? 1(B) ? 2(B) ? 3(B) ? 4(B)]
|
||||
RETURN
|
||||
|
||||
CENTRY ITYIC,[CHAN] ; READ TTY INTERRUPT CHARACTER
|
||||
|
||||
MOVE A,CHAN ; CHANNEL
|
||||
.ITYIC A,
|
||||
SETO A,
|
||||
RETURN
|
||||
|
||||
CENTRY SYSLISTEN,[CHAN] ; NCHARS = SYSLISTEN(CHAN)
|
||||
|
||||
SYSCAL LISTEN,[CHAN ? MOVEM B],LI$LOS
|
||||
MOVE A,B
|
||||
LI$RET: RETURN
|
||||
LI$LOS: MOVN A,A
|
||||
GO LI$RET
|
||||
|
||||
CENTRY RCPOS,[CHAN] ; READ TTY CURSOR POSITION (V,,H)
|
||||
|
||||
SYSCAL RCPOS,[CHAN ? 2000,,B],RC$LOS
|
||||
MOVE A,B
|
||||
RC$RET: RETURN
|
||||
RC$LOS: MOVN A,A
|
||||
GO RC$RET
|
||||
|
||||
CENTRY SCML,[CHAN,NUMBER]
|
||||
|
||||
SYSCAL SCML,[CHAN ? NUMBER]
|
||||
RETURN
|
||||
|
||||
CENTRY GETCPU ; RETURN CPU TIME IN 4.069 USEC
|
||||
|
||||
.SUSET [24,,A]
|
||||
RETURN
|
||||
|
||||
CENTRY CPUTM ; RETURN CPU TIME IN 1/60 SECONDS
|
||||
|
||||
.SUSET [24,,A]
|
||||
LSH A,-12.
|
||||
RETURN
|
||||
|
||||
CENTRY SLEEP,[TIME] ; GO TO SLEEP
|
||||
|
||||
MOVE A,TIME
|
||||
.SLEEP A,
|
||||
RETURN
|
||||
|
||||
CENTRY ETIME ; RETURN A TIME FOR ELAPSED TIME MEASUREMENT
|
||||
|
||||
.RDTIME A,
|
||||
LSH A,1
|
||||
RETURN
|
||||
|
||||
CENTRY NOW,[PCAL] ; GET CURRENT DATE AND TIME
|
||||
|
||||
HRRZ D,PCAL ; CAL POINTER
|
||||
.RDATE C,
|
||||
LDB A,[360600,,C] ; HIGH-ORDER YEAR SIXBIT
|
||||
SUBI A,20
|
||||
IMULI A,10.
|
||||
LDB B,[300600,,C] ; LOW-ORDER YEAR SIXBIT
|
||||
SUBI B,20
|
||||
ADDI A,1900.(B) ; YEAR
|
||||
MOVEM A,(D)
|
||||
|
||||
LDB A,[220600,,C] ; HIGH-ORDER MONTH
|
||||
SUBI A,20
|
||||
IMULI A,10.
|
||||
LDB B,[140600,,C] ; LOW-ORDER MONTH
|
||||
SUBI B,20
|
||||
ADDI A,(B)
|
||||
MOVEM A,1(D) ; MONTH
|
||||
|
||||
LDB A,[060600,,C] ; HIGH-ORDER DAY
|
||||
SUBI A,20
|
||||
IMULI A,10.
|
||||
LDB B,[000600,,C] ; LOW-ORDER DAY
|
||||
SUBI B,20
|
||||
ADDI A,(B)
|
||||
MOVEM A,2(D) ; DAY
|
||||
|
||||
.RTIME C,
|
||||
LDB A,[360600,,C] ; HIGH-ORDER HOUR
|
||||
SUBI A,20
|
||||
IMULI A,10.
|
||||
LDB B,[300600,,C] ; LOW-ORDER HOUR
|
||||
SUBI B,20
|
||||
ADDI A,(B)
|
||||
MOVEM A,3(D) ; HOUR
|
||||
|
||||
LDB A,[220600,,C] ; HIGH-ORDER MINUTE
|
||||
SUBI A,20
|
||||
IMULI A,10.
|
||||
LDB B,[140600,,C] ; LOW-ORDER MINUTE
|
||||
SUBI B,20
|
||||
ADDI A,(B)
|
||||
MOVEM A,4(D) ; MINUTE
|
||||
|
||||
LDB A,[060600,,C] ; HIGH-ORDER SECOND
|
||||
SUBI A,20
|
||||
IMULI A,10.
|
||||
LDB B,[000600,,C] ; LOW-ORDER SECOND
|
||||
SUBI B,20
|
||||
ADDI A,(B)
|
||||
MOVEM A,5(D) ; SECOND
|
||||
|
||||
MOVEI A,(D)
|
||||
RETURN
|
||||
|
||||
CENTRY CORBLK,[A1,A2,A3,A4,A5] ; PERFORM PAGE HACKING
|
||||
|
||||
SYSCAL CORBLK,[A1 ? A2 ? A3 ? A4 ? A5]
|
||||
RETURN
|
||||
|
||||
CENTRY CORTYP,[PAGNO,OUTPUT] ; GET INFORMATION ABOUT PAGE
|
||||
|
||||
MOVE B,OUTPUT
|
||||
SYSCAL CORTYP,[PAGNO ? 2000,,(B) ? 2000,,1(B) ? 2000,,2(B)
|
||||
2000,,3(B)]
|
||||
RETURN
|
||||
|
||||
CENTRY PAGEID,[VPN,IDN] ; GET NAMED PUBLIC PAGE
|
||||
|
||||
SYSCAL PAGEID,[VPN ? IDN ? 2000,,B],PI$LOS
|
||||
MOVE A,B
|
||||
PI$RET: RETURN
|
||||
PI$LOS: MOVN A,A
|
||||
GO PI$RET
|
||||
|
||||
CENTRY PGWRIT,[JOB,VPN]
|
||||
|
||||
SYSCAL PGWRIT,[JOB ? VPN]
|
||||
RETURN
|
||||
|
||||
CENTRY RSNAME ; READ SNAME
|
||||
|
||||
.SUSET [.RSNAM,,A]
|
||||
RETURN
|
||||
|
||||
CENTRY SSNAME,[NAME] ; SET SNAME
|
||||
|
||||
MOVE A,NAME
|
||||
.SUSET [.SSNAM,,A]
|
||||
RETURN
|
||||
|
||||
CENTRY RUNAME ; READ USER NAME
|
||||
|
||||
.SUSET [.RUNAM,,A]
|
||||
RETURN
|
||||
|
||||
CENTRY RSUSET,[WHERE]
|
||||
|
||||
HRLZ A,WHERE
|
||||
TLZ A,600000 ; CLEAR DIRECTION AND BLOCK BITS
|
||||
ADDI A,A ; RESULT TO A
|
||||
.SUSET A ; DO IT
|
||||
RETURN
|
||||
|
||||
CENTRY WSUSET,[WHERE,WHAT]
|
||||
|
||||
HRLZ B,WHERE
|
||||
TLO B,400000 ; SET DIRECTION BIT
|
||||
TLZ B,200000 ; CLEAR BLOCK BIT
|
||||
ADDI B,A ; TAKE WORD FROM A
|
||||
MOVE A,WHAT
|
||||
.SUSET B ; DO IT
|
||||
RETURN
|
||||
|
||||
CENTRY RUSET,[WHO,WHERE]
|
||||
|
||||
HRLZ B,WHERE
|
||||
TLZ B,600000 ; CLEAR DIRECTION AND BLOCK BITS
|
||||
ADDI B,A ; RESULT TO A
|
||||
HRRZ A,WHO
|
||||
ANDI A,17 ; CHANNEL NUMBER
|
||||
LSH A,23.
|
||||
IOR A,[.USET B]
|
||||
XCT A ; DO IT
|
||||
RETURN
|
||||
|
||||
CENTRY WUSET,[WHO,WHERE,WHAT]
|
||||
|
||||
HRLZ B,WHERE
|
||||
TLO B,400000 ; SET DIRECTION BIT
|
||||
TLZ B,200000 ; CLEAR DIRECTION BIT
|
||||
ADDI B,A ; TAKE WORD FROM A
|
||||
HRRZ C,WHO
|
||||
ANDI C,17 ; CHANNEL NUMBER
|
||||
LSH C,23.
|
||||
IOR C,[.USET B]
|
||||
MOVE A,WHAT
|
||||
XCT C ; DO IT
|
||||
RETURN
|
||||
|
||||
CENTRY WUSRVAR,[JOB,SPEC,VALUE]
|
||||
|
||||
SETZ A,
|
||||
SYSCAL USRVAR,[JOB ? SPEC ? VALUE]
|
||||
RETURN
|
||||
|
||||
CENTRY DELETE,[FILNAM],[FDEV,FDIR,FFN1,FFN2] ; DELETE A FILE
|
||||
|
||||
MOVEI A,FDEV ; POINTER TO FILESPEC
|
||||
CALL FPARSE,[FILNAM,A] ; CONSTRUCT FILESPEC
|
||||
MOVEI A,FDEV
|
||||
CALL SYSDELETE,[A] ; DELETE THAT FILE
|
||||
RETURN
|
||||
|
||||
CENTRY SYSDELETE,[FILSPC] ; DELETE FILE
|
||||
|
||||
MOVE B,FILSPC ; ADDRESS OF FILESPEC BLOCK
|
||||
HRLZI C,(SIXBIT/DSK/)
|
||||
SKIPN (B)
|
||||
MOVEM C,(B)
|
||||
.SUSET [.RSNAM,,C]
|
||||
SKIPN 3(B)
|
||||
MOVEM C,3(B)
|
||||
SYSCAL DELETE,[(B) ? 1(B) ? 2(B) ? 3(B)]
|
||||
RETURN
|
||||
|
||||
CENTRY RENMWO,[CHAN,FILSPC] ; RENAME FILE OPEN FOR OUTPUT
|
||||
|
||||
HRRZ B,FILSPC
|
||||
SYSCAL RENMWO,[CHAN ? 1(B) ? 2(B)]
|
||||
RETURN
|
||||
|
||||
CENTRY SYSRNM,[FILSP1,FILSP2]
|
||||
|
||||
HRRZ B,FILSP1
|
||||
HRRZ C,FILSP2
|
||||
SYSCAL RENAME,[(B) ? 1(B) ? 2(B) ? 3(B) ? 1(C) ? 2(C) ? 3(C)]
|
||||
RETURN
|
||||
|
||||
CENTRY SYSLNK,[FILSP1,FILSP2]
|
||||
|
||||
HRRZ B,FILSP1
|
||||
HRRZ C,FILSP2
|
||||
SYSCAL MLINK,[(B) ? 1(B) ? 2(B) ? 3(B) ? 1(C) ? 2(C) ? 3(C)]
|
||||
RETURN
|
||||
|
||||
CENTRY DIRSIZ,[CHAN,BLOCK] ; WRITES 2 VALUES
|
||||
|
||||
HRRZ B,BLOCK
|
||||
SYSCAL DIRSIZ,[CHAN ? (B) ? 1(B)]
|
||||
RETURN
|
||||
|
||||
CENTRY TRANAD,[JOB,FROM,TO,FLAGS]
|
||||
|
||||
HRRZ B,JOB
|
||||
HRL B,FLAGS
|
||||
HRRZ C,FROM ; FROM FILESPEC
|
||||
HRLI C,-4 ; MAKE IT A CPTR
|
||||
HRRZ D,TO ; TO FILESPEC
|
||||
HRLI D,-4 ; MAKE IT A CPTR
|
||||
SYSCAL TRANAD,[B ? C ? D]
|
||||
RETURN
|
||||
|
||||
CENTRY TRANCL,[JOB,FLAGS]
|
||||
|
||||
HRRZ B,JOB
|
||||
HRL B,FLAGS
|
||||
SKIPN FLAGS
|
||||
HRLI B,300003 ; DEFAULT FLAGS
|
||||
SYSCAL TRANCL,[B]
|
||||
RETURN
|
||||
|
||||
CENTRY TRANDL,[JOB,FILSPC,FLAGS]
|
||||
|
||||
HRRZ B,JOB
|
||||
HRL B,FLAGS
|
||||
HRRZ C,FILSPC
|
||||
HRLI C,-4 ; MAKE IT A CPTR
|
||||
SYSCAL TRANDL,[B ? C]
|
||||
RETURN
|
||||
|
||||
CENTRY SYSLOAD,[JOB,CHAN],[RCODE,OLDIOC] ; LOAD A PROGRAM
|
||||
|
||||
SETZM RCODE
|
||||
CALL ON,[[[2]],[[1]]]
|
||||
MOVEM A,OLDIOC
|
||||
|
||||
SYSCAL LOAD,[JOB ? CHAN],LD$LOS
|
||||
LD$1: CALL ON,[[[2]],OLDIOC]
|
||||
MOVE A,RCODE
|
||||
RETURN
|
||||
LD$LOS: SETOM RCODE
|
||||
GO LD$1
|
||||
|
||||
CENTRY PDUMP,[JOBCH,DSKCH]
|
||||
|
||||
SETZ B,
|
||||
SYSCAL PDUMP,[JOBCH ? DSKCH ? B]
|
||||
RETURN
|
||||
|
||||
CENTRY UCLOSE,[JCHAN] ; DESTROY INFERIOR JOB
|
||||
|
||||
MOVE A,JCHAN
|
||||
ANDI A,17
|
||||
LSH A,23.
|
||||
IOR A,[.UCLOSE]
|
||||
XCT A
|
||||
RETURN
|
||||
|
||||
CENTRY SYSDISOWN,[JCHAN]
|
||||
|
||||
SYSCAL DISOWN,[JCHAN]
|
||||
RETURN
|
||||
|
||||
CENTRY REOWN,[JCHAN]
|
||||
|
||||
SYSCAL REOWN,[JCHAN]
|
||||
RETURN
|
||||
|
||||
CENTRY SYSDTACH,[JCHAN]
|
||||
|
||||
SYSCAL DETACH,[JCHAN]
|
||||
RETURN
|
||||
|
||||
CENTRY SYSATACH,[JCHAN,TTY] ; TTY<0 => DEFAULT
|
||||
|
||||
SKIPGE TTY
|
||||
GO AT$1
|
||||
SYSCAL ATTACH,[JCHAN ? TTY]
|
||||
AT$RET: RETURN
|
||||
AT$1: SYSCAL ATTACH,[JCHAN]
|
||||
GO AT$RET
|
||||
|
||||
CENTRY ATTY,[JOB] ; GIVE TTY TO INFERIOR
|
||||
|
||||
MOVE B,JOB
|
||||
ANDI B,17
|
||||
LSH B,23.
|
||||
IOR B,[.ATTY]
|
||||
SETZ A,
|
||||
XCT B
|
||||
SETO A,
|
||||
RETURN
|
||||
|
||||
CENTRY DTTY,[JOB] ; TAKE TTY FROM INFERIOR
|
||||
|
||||
MOVE B,JOB
|
||||
ANDI B,17
|
||||
LSH B,23.
|
||||
IOR B,[.DTTY]
|
||||
SETZ A,
|
||||
XCT B
|
||||
SETO A,
|
||||
RETURN
|
||||
|
||||
CENTRY WFNZ,[PTR] ; WAIT FOR WORD TO BECOME NON-ZERO
|
||||
|
||||
MOVE A,PTR
|
||||
SKIPN (A)
|
||||
.HANG
|
||||
MOVE A,(A)
|
||||
RETURN
|
||||
|
||||
CENTRY WFZ,[PTR] ; WAIT FOR WORD TO BECOME ZERO
|
||||
|
||||
MOVE A,PTR
|
||||
SKIPE (A)
|
||||
.HANG
|
||||
MOVE A,(A)
|
||||
RETURN
|
||||
|
||||
CENTRY VAL7RET,[STR] ; VALRET AN ASCIZ STRING
|
||||
|
||||
HRRZ A,STR
|
||||
HRLI A,(.VALUE)
|
||||
XCT A
|
||||
RETURN
|
||||
|
||||
CENTRY DEMSIG,[DEMON] ; SIGNAL A DEMON PROCESS
|
||||
|
||||
SYSCAL DEMSIG,[DEMON]
|
||||
RETURN
|
||||
|
||||
CENTRY SSTATUS,[VALBLK] ; RETURNS 7 VALUES
|
||||
|
||||
HRRZ B,VALBLK
|
||||
SYSCAL SSTATUS,[MOVEM (B) ? MOVEM 1(B) ? MOVEM 2(B)
|
||||
MOVEM 3(B) ? MOVEM 4(B) ? MOVEM 5(B) ? MOVEM 6(B)]
|
||||
RETURN
|
||||
|
||||
CENTRY MAKTAG,[TAGP]
|
||||
|
||||
HRRZ A,TAGP ; TAG POINTER
|
||||
MOVE B,(P) ; RETURN PC
|
||||
MOVEM B,(A) ; SAVE RETURN PC
|
||||
MOVEI B,-2(P) ; STACK POINTER BEFORE CALL
|
||||
MOVEM B,1(A) ; SAVE STACK POINTER
|
||||
RETURN
|
||||
|
||||
CENTRY GOTAG,[TAGP]
|
||||
|
||||
MCALL DISMISS
|
||||
MOVE A,TAGP
|
||||
MOVE P,1(A)
|
||||
HRRZ D,(A)
|
||||
GO (D)
|
||||
|
||||
END
|
||||
196
src/clib/c10tap.cmid
Normal file
196
src/clib/c10tap.cmid
Normal file
@@ -0,0 +1,196 @@
|
||||
;
|
||||
; C10TAP - MAG TAPE INTERFACE
|
||||
;
|
||||
; This file is ITS dependent.
|
||||
;
|
||||
|
||||
TITLE C10TAPE
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
TAPIN==17 ; TAPE CHANNEL
|
||||
TPIBSZ==200 ; SIZE OF TAPE INPUT BUFFER
|
||||
TPBFSZ==2000 ; SIZE OF TAPE OUTPUT BUFFER
|
||||
|
||||
CENTRY RWND8 ; REWIND TAPE, LEAVE OPEN FOR READ
|
||||
|
||||
.CLOSE TAPIN,
|
||||
.OPEN TAPIN,[033726,,(SIXBIT/MT0/)]
|
||||
CROAK UNABLE TO OPEN TAPE FOR READING
|
||||
MOVE 0,[TAPIN,,[1]]
|
||||
.MTAPE 0,
|
||||
JFCL
|
||||
SETZM CURBLOCK
|
||||
RETURN
|
||||
|
||||
CENTRY OPEN8 ; OPEN TAPE FOR 8-BIT READ
|
||||
|
||||
MOVE A,TAPECH
|
||||
CAILE A,0
|
||||
GO OP$RTN
|
||||
CALL RWND8
|
||||
SETZM TPICNT
|
||||
SETZM TPIEOF
|
||||
SETOM CURBLOCK
|
||||
MOVEI 0,1
|
||||
MOVEM 0,TAPECH
|
||||
OP$RTN: RETURN
|
||||
|
||||
CENTRY OPNW8 ; OPEN TAPE FOR 8-BIT WRITE
|
||||
|
||||
CALL RWND8
|
||||
.OPEN TAPIN,[033707,,(SIXBIT/MT0/)]
|
||||
CROAK UNABLE TO OPEN TAPE FOR WRITING
|
||||
MOVEI A,2*TPBFSZ
|
||||
MOVEM A,TPICNT
|
||||
MOVE A,[442000,,TPIBUF]
|
||||
MOVEM A,TPIBFP
|
||||
SETOM TAPECH
|
||||
RETURN
|
||||
|
||||
CENTRY GET16 ; READ 16-BITS
|
||||
|
||||
SOSGE TPICNT
|
||||
CL TPREAD
|
||||
ILDB A,TPIBFP
|
||||
ILDB B,TPIBFP
|
||||
LSH B,10
|
||||
IOR A,B
|
||||
MOVE B,A
|
||||
ADD B,CHECKSUM
|
||||
ANDI B,0177777
|
||||
MOVEM B,CHECKSUM
|
||||
RETURN
|
||||
|
||||
CENTRY PUT16,[W] ; WRITE 16 BITS
|
||||
|
||||
MOVE C,W
|
||||
SOSGE TPICNT ; ANY ROOM ?
|
||||
CL WRTAPE ; NO, FLUSH BUFFER
|
||||
MOVE B,C
|
||||
ADD B,CHECKSUM
|
||||
ANDI B,0177777
|
||||
MOVEM B,CHECKSUM
|
||||
MOVE B,C
|
||||
LSH B,-10
|
||||
ANDI B,0377
|
||||
LSH C,10
|
||||
ANDI C,177400
|
||||
IOR B,C
|
||||
MOVE C,B
|
||||
IDPB C,TPIBFP
|
||||
RETURN
|
||||
|
||||
CENTRY SEEK8,[ACC] ; RANDOM ACCESS
|
||||
|
||||
SETZM CHARINBUF ; CLEAR GET8 BUFFER
|
||||
MOVE A,ACC
|
||||
MOVE B,A
|
||||
SUB A,CURBLOCK
|
||||
CAIE A,0
|
||||
GO L1
|
||||
|
||||
; HERE IF DESIRED BLOCK IS IN BUFFER
|
||||
|
||||
MOVEI A,2*TPIBSZ
|
||||
MOVEM A,TPICNT
|
||||
MOVE A,[441000,,TPIBUF]
|
||||
MOVEM A,TPIBFP
|
||||
SE$RET: RETURN
|
||||
|
||||
L1: SUBI A,1 ; NUMBER OF BLOCKS TO SKIP
|
||||
SETZM TPICNT
|
||||
CAIN A,0
|
||||
GO SE$RET ; WANT NEXT BLOCK, NOTHING TO SKIP
|
||||
|
||||
; HERE IF NECESSARY TO SKIP SOME BLOCKS
|
||||
|
||||
HRLZ C,A
|
||||
HRLZI A,TAPIN
|
||||
HRRI A,C
|
||||
HRRI C,6
|
||||
.MTAPE A,
|
||||
JFCL
|
||||
SUBI B,1
|
||||
MOVEM B,CURBLOCK
|
||||
RETURN
|
||||
|
||||
CENTRY CLOS8 ; CLOSE TAPE
|
||||
|
||||
SKIPGE TAPECH
|
||||
CL FLUSH8 ; FLUSH BUFFER
|
||||
CALL RWND8
|
||||
.CLOSE TAPIN,
|
||||
SETZM TAPECH
|
||||
RETURN
|
||||
|
||||
CENTRY EOF8 ; TEST FOR END-OF-FILE
|
||||
|
||||
MOVE A,TPIEOF
|
||||
RETURN
|
||||
|
||||
; *** BUFFERED I/O ROUTINES ***
|
||||
|
||||
; TPICNT - NUMBER OF 16-BIT INTEGERS IN BUFFER
|
||||
; TPIBFP - ABPTR TO NEXT 16-BIT INTEGER IN BUFFER
|
||||
; TPIBUF - THE BUFFER
|
||||
; TPIEOF - -1 IF END-OF-FILE
|
||||
|
||||
TPR1: SOSL TPICNT
|
||||
RTN
|
||||
TPREAD: MOVEI A,2*TPIBSZ
|
||||
MOVEM A,TPICNT
|
||||
MOVE A,[441000,,TPIBUF]
|
||||
MOVEM A,TPIBFP
|
||||
MOVEI A,TPIBUF
|
||||
HRLI A,-TPIBSZ
|
||||
AOS CURBLOCK
|
||||
.IOT TAPIN,A
|
||||
JUMPGE A,TPR1
|
||||
HLRES A
|
||||
ADDI A,TPIBSZ
|
||||
JUMPE A,TPR2 ; END OF FILE
|
||||
LSH A,1
|
||||
MOVEM A,TPICNT
|
||||
GO TPR1
|
||||
TPR2: SETOM TPIEOF
|
||||
SETZM TPIBUF
|
||||
RTN
|
||||
|
||||
FLUSH8: MOVEI A,2*TPBFSZ ; FLUSH (MAYBE UNFILLED) BUFFER
|
||||
SUB A,TPICNT
|
||||
ADDI A,1
|
||||
LSH A,-1
|
||||
MOVN A,A
|
||||
HRLZ A,A
|
||||
SKIPA
|
||||
|
||||
WRTAPE: HRLZI A,-TPBFSZ ; THIS IS SKIPPED FROM FLUSH8
|
||||
HRRI A,TPIBUF
|
||||
.IOT TAPIN,A ; WRITE BUFFER
|
||||
MOVEI A,2*TPBFSZ-1
|
||||
MOVEM A,TPICNT
|
||||
MOVE A,[442000,,TPIBUF]
|
||||
MOVEM A,TPIBFP
|
||||
RTN
|
||||
|
||||
; *** BUFFERED I/O VARIABLES ***
|
||||
|
||||
.UDATA
|
||||
TAPECH: BLOCK 1 ; 0 - CLOSED
|
||||
; 1 - OPEN FOR READ
|
||||
; -1 - OPEN FOR WRITE
|
||||
|
||||
TPICNT: BLOCK 1 ; TAPE I/O VARIABLES
|
||||
TPIBFP: BLOCK 1
|
||||
TPIEOF: BLOCK 1
|
||||
TPIBUF: BLOCK TPBFSZ
|
||||
|
||||
MDATA CURBLOCK
|
||||
BLOCK 1
|
||||
MDATA CHECKSUM
|
||||
BLOCK 1
|
||||
MDATA CHARINBUF
|
||||
BLOCK 1
|
||||
|
||||
END
|
||||
111
src/clib/c10tmm.cmid
Normal file
111
src/clib/c10tmm.cmid
Normal file
@@ -0,0 +1,111 @@
|
||||
;
|
||||
; C10TMM - Program to determine the timing constants for
|
||||
; the C timing package (C10TMR). The computed
|
||||
; times are left in TIME1, TIME2, TIME3. Times
|
||||
; are in nanoseconds.
|
||||
;
|
||||
; This file is ITS dependent.
|
||||
; This is a stand-alone program.
|
||||
;
|
||||
|
||||
A==1
|
||||
B==2
|
||||
C==3
|
||||
D==4
|
||||
P==17
|
||||
CL==PUSHJ P,
|
||||
RTN==POPJ P,
|
||||
GO==JRST
|
||||
.CCALL==1_27.
|
||||
|
||||
TP"=16 ; TIME STACK POINTER
|
||||
%TPROC==0 ; THE PROCEDURE POINTER
|
||||
%TNAME==1 ; THE PROCEDURE NAME (SNARFED FROM PROCEDURE)
|
||||
%TNCAL==2 ; THE NUMBER OF CALLS
|
||||
%TTIME==3 ; THE TOTAL AMOUNT OF ACCUMULATED TIME
|
||||
%TSIZE==4 ; SIZE OF TIME TABLE ENTRY
|
||||
%FTABL==0 ; POINTER TO TIME TABLE ENTRY
|
||||
%FTIME==1 ; ACCUMULATED OR START TIME
|
||||
%FRTNA==2 ; ACTUAL RETURN ADDRESS
|
||||
%FSIZE==3 ; SIZE OF STACK FRAME
|
||||
|
||||
TIME1: 0
|
||||
TIME2: 0
|
||||
TIME3: 0
|
||||
TIME4: 0
|
||||
|
||||
START: MOVE P,[-2000,,PDL]
|
||||
MOVE A,[JSR UUOH]
|
||||
MOVEM A,41
|
||||
.SUSET [24,,TIME1]
|
||||
CL TSUSET
|
||||
.SUSET [24,,TIME2]
|
||||
CL TUUO
|
||||
.SUSET [24,,TIME3]
|
||||
CL TEPILOG
|
||||
.SUSET [24,,TIME4]
|
||||
MOVE A,TIME2
|
||||
SUB A,TIME1
|
||||
IMULI A,4069.
|
||||
IDIVI A,1000.
|
||||
MOVEM A,TIME1
|
||||
MOVE A,TIME3
|
||||
SUB A,TIME2
|
||||
IMULI A,4069.
|
||||
IDIVI A,1000.
|
||||
MOVEM A,TIME2
|
||||
MOVE A,TIME4
|
||||
SUB A,TIME3
|
||||
IMULI A,4069.
|
||||
IDIVI A,500.
|
||||
MOVEM A,TIME3
|
||||
SETZM TIME4
|
||||
.VALUE
|
||||
|
||||
TSUSET: REPEAT 1000.,[.SUSET [24,,C]
|
||||
]
|
||||
RTN
|
||||
|
||||
TUUO: REPEAT 1000.,[
|
||||
.CCALL 2,0
|
||||
]
|
||||
RTN
|
||||
|
||||
UUOH: 0
|
||||
GO UUO$HANDLER
|
||||
|
||||
UUO$HANDLER:
|
||||
|
||||
MOVEM D,USAVED
|
||||
LDB D,[330500,,ZERO]
|
||||
GO @UUOH(D)
|
||||
|
||||
USAVED: 0
|
||||
ZERO: 0
|
||||
BAR: -1
|
||||
BAR2: 0
|
||||
0
|
||||
0
|
||||
BAR3: 0
|
||||
0
|
||||
0
|
||||
0
|
||||
|
||||
TEPILOG:
|
||||
MOVEI TP,BAR2
|
||||
MOVEI B,BAR3
|
||||
MOVEI A,0
|
||||
REPEAT 500.,[
|
||||
MOVE 0,C
|
||||
SUBI C,37
|
||||
SUB C,%FTIME(TP)
|
||||
MOVE C,%FTABL(TP)
|
||||
ADDM C,%TTIME(B)
|
||||
SUBI TP,%FSIZE
|
||||
ADDI 0,37
|
||||
SUBM 0,%FTIME(TP)
|
||||
GO @[.+1](A) ; TO NEXT LOCATION
|
||||
]
|
||||
RTN
|
||||
PDL: BLOCK 2000
|
||||
END START
|
||||
149
src/clib/c10tmr.cmid
Normal file
149
src/clib/c10tmr.cmid
Normal file
@@ -0,0 +1,149 @@
|
||||
;
|
||||
; TIMER - Version of runtime to time procedure calls
|
||||
;
|
||||
; This file is ITS dependent.
|
||||
; (Dependency is system-call to get runtime.)
|
||||
;
|
||||
|
||||
TITLE TIMER
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
TIMSIZ==1000.
|
||||
IF1,[
|
||||
KLFLAG==0
|
||||
PRINTX \KL10 (YES/NO)? \
|
||||
.TTYMAC TIMEQ
|
||||
IFSE TIMEQ,YES,KLFLAG==1
|
||||
TERMIN
|
||||
]
|
||||
|
||||
TP"=16 ; TIME STACK POINTER
|
||||
|
||||
; TIME TABLE ENTRY WORDS
|
||||
|
||||
%TPROC==0 ; THE PROCEDURE POINTER
|
||||
%TNAME==1 ; THE PROCEDURE NAME (SNARFED FROM PROCEDURE)
|
||||
%TNCAL==2 ; THE NUMBER OF CALLS
|
||||
%TTIME==3 ; THE TOTAL AMOUNT OF ACCUMULATED TIME
|
||||
%TSIZE==4 ; SIZE OF TIME TABLE ENTRY
|
||||
|
||||
; TIME STACK FRAME WORDS
|
||||
|
||||
%FTABL==0 ; POINTER TO TIME TABLE ENTRY
|
||||
%FTIME==1 ; ACCUMULATED OR START TIME
|
||||
%FRTNA==2 ; ACTUAL RETURN ADDRESS
|
||||
%FSIZE==3 ; SIZE OF STACK FRAME
|
||||
|
||||
; TIMING CONSTANTS (IN NANOSECONDS)
|
||||
; COMPUTED BY PROGRAM 'TTIMM'
|
||||
|
||||
IFE KLFLAG,[
|
||||
SUSTIM==387909. ;TIME FOR .SUSET
|
||||
UUOTIM==27929. ;TIME FOR UUO DISPATCH
|
||||
EPITIM==30891. ;TIME FOR EPILOG
|
||||
]
|
||||
|
||||
IFN KLFLAG,[
|
||||
SUSTIM==71630.
|
||||
UUOTIM==3373.
|
||||
EPITIM==4663.
|
||||
]
|
||||
|
||||
;
|
||||
; .CCALL HANDLER (TIMING VERSION)
|
||||
;
|
||||
|
||||
IENTRY UTCALL
|
||||
|
||||
.SUSET [24,,C] ; JOB ACCUMULATED TIME TO C
|
||||
SKIPN TIMING" ; IS TIMING ON ?
|
||||
GO UT$1 ; NO, RESUME NORMAL OPERATION
|
||||
SUBI C,<UUOTIM+SUSTIM>/4069.
|
||||
; FUDGE FOR SUSET AND TIME IT TOOK
|
||||
; TO GET HERE
|
||||
SUBM C,%FTIME(TP) ; DETERMINE CALLER'S ACCUMULATED TIME
|
||||
ADDI TP,%FSIZE ; ALLOCATE NEW TIME FRAME
|
||||
|
||||
HRRZ B,40 ; CALLED ROUTINE
|
||||
HRRZ D,-1(B) ; TIMTAB POINTER OR PROC NAME
|
||||
CAIGE D,TIMTAB ; IS IT A TIMTAB POINTER?
|
||||
GO UT$3 ; NO
|
||||
CAMGE D,TIMEP ; IS IT A TIMTAB POINTER?
|
||||
GO UT$2 ; YES
|
||||
|
||||
UT$3: MOVE A,D ; PROC NAME
|
||||
MOVE D,TIMEP ; FIRST TIMED CALL OF ROUTINE
|
||||
CAML D,ETIMEP ; IS TIME TABLE FULL?
|
||||
GO UT$1 ; YES, IGNORE THIS CALL
|
||||
MOVEM B,%TPROC(D) ; NO - INITIALIZE NEW TIMTAB ENTRY
|
||||
MOVEM A,%TNAME(D)
|
||||
SETZM %TTIME(D)
|
||||
SETZM %TNCAL(D)
|
||||
HRRM D,-1(B) ; PUT PTR TO TIMTAB ENTRY IN NAME WORD
|
||||
MOVEI C,%TSIZE
|
||||
ADDM C,TIMEP ; ADVANCE POINTER TO NEXT FREE ENTRY
|
||||
|
||||
UT$2: ; HERE WITH PTR TO TIMTAB ENTRY IN D
|
||||
MOVEM D,%FTABL(TP) ; STORE POINTER IN TIME STACK
|
||||
AOS %TNCAL(D) ; INCREMENT USE COUNT
|
||||
|
||||
UT$1: ; CONTINUE WITH CALL PROCESSING
|
||||
HRRZ C,40 ; THE CALLED PROCEDURE
|
||||
JUMPE C,UCBAD" ; NO SUCH PROCEDURE
|
||||
HLRZ 0,-1(C) ; THE NUMBER OF FORMAL ARGS
|
||||
CAIL 0,20 ; REASONABLE NUMBER?
|
||||
GO UCBAD ; NO, NOT A PROCEDURE
|
||||
LDB B,[270400,,40] ; THE NUMBER OF ACTUAL ARGS
|
||||
SUB 0,B ; NUMBER OF ARGS NOT GIVEN
|
||||
JUMPL 0,CODE [ ; TOO MANY ARGS GIVEN
|
||||
ADD P,0 ; POP OFF EXTRA ARGS
|
||||
GO UTDOIT ; MAKE THE CALL
|
||||
]
|
||||
UTLOOP: SOJL 0,UTDOIT ; FOR EACH ARG NEEDED
|
||||
PUSH P,[0] ; PUSH ZERO ARG
|
||||
GO UTLOOP ; LOOP
|
||||
UTDOIT: SKIPN TIMING
|
||||
GO UT$4
|
||||
MOVE B,UUOH ; RETURN ADDRESS
|
||||
MOVEM B,%FRTNA(TP) ; SAVE IT
|
||||
MOVEI B,%FTIME(TP) ; CONSTRUCT .SUSET
|
||||
HRLI B,24 ; GET START TIME FOR CALLED PROC
|
||||
.SUSET B ; AND STORE IN TIME STACK FRAME
|
||||
PUSHJ P,(C) ; CALL PROCEDURE
|
||||
.SUSET [24,,C] ; JOB ACCUMULATED TIME
|
||||
MOVE 0,C
|
||||
SUBI C,SUSTIM/4069. ; FUDGE FOR .SUSET TIME
|
||||
SUB C,%FTIME(TP) ; SUBTRACT START TIME
|
||||
MOVE B,%FTABL(TP) ; TIMTAB ENTRY POINTER
|
||||
ADDM C,%TTIME(B) ; ADD TO ACCUMULATED TIME FOR CALLEE
|
||||
SUBI TP,%FSIZE ; POP TIME STACK FRAME
|
||||
ADDI 0,<EPITIM>/4069. ; FUDGE
|
||||
SUBM 0,%FTIME(TP) ; ADJUST START TIME OF CALLER
|
||||
GO @%FRTNA+%FSIZE(TP) ; RETURN TO CALLER
|
||||
|
||||
UT$4: PUSH P,UUOH"
|
||||
GO (C)
|
||||
|
||||
IENTRY TINIT
|
||||
|
||||
SETOM TIMING"
|
||||
MOVEI A,UTCALL
|
||||
MOVEM A,UUOTAB"+1
|
||||
MOVEI TP,TIMSTK
|
||||
MOVEM TP,TPINIT"
|
||||
MOVEI A,TPRT"
|
||||
MOVEM A,EXITER"
|
||||
GO LINIT"
|
||||
|
||||
.IDATA
|
||||
MDATA TIMEP
|
||||
TIMTAB
|
||||
MDATA ETIMEP
|
||||
TIMTAB+<TIMSIZ*%TSIZE>
|
||||
.UDATA
|
||||
MDATA TIMTAB
|
||||
BLOCK TIMSIZ*%TSIZE
|
||||
MDATA TIMSTK
|
||||
BLOCK TIMSIZ
|
||||
END
|
||||
151
src/clib/c10tpr.c
Normal file
151
src/clib/c10tpr.c
Normal file
@@ -0,0 +1,151 @@
|
||||
# include "clib/c.defs"
|
||||
# include "clib/its.bits"
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
C10TPR - Printing Routine for C Timer Package
|
||||
*ITS*
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
# rename null "$NULL$"
|
||||
# rename timing "TIMING"
|
||||
# rename timtab "TIMTAB"
|
||||
# rename timep "TIMEP"
|
||||
# rename tprt "TPRT"
|
||||
|
||||
struct _tentry {int *proc, pname, count, time;};
|
||||
# define tentry struct _tentry
|
||||
|
||||
extern int timing;
|
||||
extern tentry timtab[], *timep;
|
||||
extern int cout;
|
||||
|
||||
/* All times are kept in machine-dependent Units
|
||||
and converted upon output to the appropriate
|
||||
units.
|
||||
*/
|
||||
|
||||
tprt ()
|
||||
|
||||
{int fout, /* output file */
|
||||
total_time, /* total CPU time used */
|
||||
smallest, /* smallest average time */
|
||||
time, /* time used by current routine */
|
||||
average, /* average time of current routine */
|
||||
percent, /* percentage CPU time, current routine */
|
||||
cpercent, /* cumulative percentage CPU time */
|
||||
ctime, /* cumulative CPU time */
|
||||
count, /* number of calls, current routine */
|
||||
ncalls, /* total number of calls */
|
||||
namep, /* pointer to current routine name */
|
||||
nulltime, /* time to call null routine */
|
||||
t,
|
||||
c;
|
||||
|
||||
tentry *ip, *ip1;
|
||||
|
||||
t = rsuset (URUNT);
|
||||
c = 50;
|
||||
timing = -1;
|
||||
while (--c >= 0)
|
||||
{null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
null ();
|
||||
}
|
||||
timing = 0;
|
||||
|
||||
fout = copen ("timer.output", 'a');
|
||||
if (fout<0) fout = copen ("timout", 'w');
|
||||
if (fout<0) fout = cout;
|
||||
|
||||
cprint (fout, "\n\n\n *** TIMING INFORMATION ***\n\n");
|
||||
cprint (fout, "TIME(usec) PERCENT CUM. %% NO. CALLS AVG. TIME ROUTINE NAME\n\n");
|
||||
|
||||
/* null entry should be last */
|
||||
|
||||
--timep;
|
||||
nulltime = timep->time / timep->count;
|
||||
|
||||
/* sort entries in order of decreasing CPU time used */
|
||||
|
||||
for (ip=timtab;ip<timep;++ip)
|
||||
for (ip1 = ip+1;ip1<timep;++ip1)
|
||||
if (ip1->time > ip->time)
|
||||
bswap (ip, ip1, 4);
|
||||
|
||||
total_time = 0;
|
||||
for (ip=timtab;ip<timep;++ip)
|
||||
total_time =+ ip->time;
|
||||
|
||||
ncalls = 0;
|
||||
smallest = 10000; /* big number */
|
||||
ctime = 0;
|
||||
for (ip=timtab;ip<timep;++ip)
|
||||
{time = ip->time;
|
||||
ctime =+ time;
|
||||
percent = (time * 1000) / total_time;
|
||||
cpercent = (ctime * 1000) / total_time;
|
||||
count = ip->count;
|
||||
ncalls =+ count;
|
||||
namep = (ip->pname) | 0440700000000;
|
||||
average = time/count;
|
||||
if (average<smallest && average>0) smallest=average;
|
||||
cprint (fout, "%10d%8d.%1d%8d.%1d",
|
||||
u2mic (time), percent/10, percent%10,
|
||||
cpercent/10, cpercent%10);
|
||||
cprint (fout, "%11d%12d ", count, u2mic (average));
|
||||
while (c = ildb (&namep)) cputc (c, fout);
|
||||
cputc ('\n', fout);
|
||||
}
|
||||
|
||||
if (smallest<nulltime) nulltime=smallest;
|
||||
time = ncalls * nulltime;
|
||||
percent = (time * 1000) / total_time; /* percent * 10 */
|
||||
|
||||
cprint (fout, "\nTOTAL TIME = %d MSEC.\n", u2mil (total_time));
|
||||
cprint (fout, "PROC. CALL TIME = %d USEC.\n", u2mic (nulltime));
|
||||
cprint (fout, "NO. CALLS = %d\n", ncalls);
|
||||
cprint (fout, "EST. CALL OVERHEAD = %d.%d %%\n",
|
||||
percent/10, percent%10);
|
||||
|
||||
cclose (fout);
|
||||
}
|
||||
|
||||
u2mil (t) /* convert Units to Milliseconds */
|
||||
|
||||
{return ((t * 407) / 100000);}
|
||||
|
||||
u2mic (t) /* convert Units to Microseconds */
|
||||
|
||||
{return ((t * 407) / 100);}
|
||||
|
||||
bswap (p, q, n) int *p, *q;
|
||||
|
||||
{int t;
|
||||
|
||||
while (--n >= 0)
|
||||
{t = *p;
|
||||
*p++ = *q;
|
||||
*q++ = t;
|
||||
}
|
||||
}
|
||||
|
||||
null () {;}
|
||||
375
src/clib/c10tty.c
Normal file
375
src/clib/c10tty.c
Normal file
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* C TTY Package
|
||||
*
|
||||
* routines:
|
||||
*
|
||||
* tyiopn - open TTY input channel
|
||||
* tyi - read char from TTY (buffered)
|
||||
* utyi - read char from TTY (unbuffered)
|
||||
* get_buf - read string from TTY
|
||||
* setprompt - set default TYI prompt string
|
||||
* tyoopn - open TTY output channel
|
||||
* tyo - output char to TTY (buffered)
|
||||
* utyo - output char to TTY (unbuffered)
|
||||
* spctty - output display code (unbuffered)
|
||||
* tyos - output string to TTY (buffered)
|
||||
* tyo_flush - flush TTY output buffer
|
||||
*
|
||||
* global variables:
|
||||
*
|
||||
* ttynp - ^L handler
|
||||
*
|
||||
* internal routines:
|
||||
*
|
||||
* ttyih - TTY interrupt handler
|
||||
* ctrlch - return display width of char
|
||||
*
|
||||
*/
|
||||
|
||||
# include "c.defs"
|
||||
|
||||
# define tty_input_buffer_size 120
|
||||
# define tty_output_buffer_size 60
|
||||
|
||||
# rename tty_input_channel "TYICHN"
|
||||
# rename tty_output_channel "TYOCHN"
|
||||
# rename tty_device_code "TTYDEV"
|
||||
# rename tty_input_buffer "TYIBUF"
|
||||
# rename tty_input_ptr "TYIPTR"
|
||||
# rename tty_input_count "TYICNT"
|
||||
# rename tty_output_buffer "TYOBUF"
|
||||
# rename tty_output_ptr "TYOPTR"
|
||||
# rename tty_output_count "TYOCNT"
|
||||
# rename tty_output_bptr "TYOBPT"
|
||||
# rename tty_default_prompt "TTYDPR"
|
||||
|
||||
int tty_input_channel -1;
|
||||
int tty_output_channel -1;
|
||||
int tty_device_code -1;
|
||||
char tty_input_buffer[tty_input_buffer_size];
|
||||
char *tty_input_ptr;
|
||||
int tty_input_count;
|
||||
char tty_output_buffer[tty_output_buffer_size];
|
||||
char *tty_output_ptr {tty_output_buffer};
|
||||
int tty_output_count;
|
||||
int tty_output_bptr;
|
||||
char *tty_default_prompt;
|
||||
|
||||
int ttxnp(); /* default TTY ^L handler */
|
||||
int (*ttynp)() {ttxnp}; /* called on ^L */
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
TYI - Read Character From TTY (buffered)
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
tyi ()
|
||||
|
||||
{while (tty_input_count <= 0)
|
||||
{if (tty_input_channel < 0) tyiopn ();
|
||||
tty_input_count = get_buf (tty_input_buffer,
|
||||
tty_input_buffer_size, '\r', "");
|
||||
tty_input_ptr = tty_input_buffer;
|
||||
if (tty_input_count == 0) return (0);
|
||||
}
|
||||
--tty_input_count;
|
||||
return (*tty_input_ptr++);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
UTYO - output character to TTY (unbuffered)
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
utyo (c)
|
||||
|
||||
{if (tty_output_channel >= 0 || tyoopn() >= 0)
|
||||
{if (tty_output_count > 0) tyo_flush ();
|
||||
c =& 0177;
|
||||
if (c != 16) uoiot (tty_output_channel, c);
|
||||
else
|
||||
{uoiot (tty_output_channel, '^');
|
||||
uoiot (tty_output_channel, 'P');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
TYO - output character to TTY
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
tyo (c)
|
||||
|
||||
{c =& 0177;
|
||||
|
||||
if (tty_output_channel >= 0 || tyoopn() >= 0)
|
||||
{if (c != 16) {*tty_output_ptr++ = c; ++tty_output_count;}
|
||||
else
|
||||
{*tty_output_ptr++ = '^';
|
||||
*tty_output_ptr++ = 'P';
|
||||
tty_output_count =+ 2;
|
||||
}
|
||||
if (c=='\r' || tty_output_count >= tty_output_buffer_size-2)
|
||||
tyo_flush ();
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
TYO_FLUSH - flush TTY output buffer
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
tyo_flush ()
|
||||
|
||||
{if (tty_output_channel >= 0 && tty_output_count > 0)
|
||||
{siot (tty_output_channel, tty_output_bptr,
|
||||
tty_output_count);
|
||||
tty_output_ptr = tty_output_buffer;
|
||||
tty_output_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
TYOS - Output String to TTY
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
tyos (s) char s[];
|
||||
|
||||
{int c;
|
||||
|
||||
while (c = *s++) tyo (c=='\n' ? '\r' : c);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
SPCTTY - Send "special" display control character to TTY.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
spctty (c)
|
||||
|
||||
{if (tty_output_channel >= 0 || tyoopn() >= 0)
|
||||
{if (tty_output_count > 0) tyo_flush ();
|
||||
uoiot (tty_output_channel, 16);
|
||||
uoiot (tty_output_channel, c);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
UTYI - read character from TTY (unbuffered and unechoed)
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int utyi ()
|
||||
|
||||
{if (tty_input_channel<0) tyiopn ();
|
||||
if (tty_output_count > 0) tyo_flush ();
|
||||
return (uiiot (tty_input_channel));
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
GET_BUF - Read characters from TTY until end-of-file
|
||||
simulated or given break character seen.
|
||||
Read characters into given buffer, including
|
||||
the terminating break character (if any).
|
||||
Return a count of the number of characters
|
||||
placed in the buffer. The given prompt string
|
||||
will be printed first; it will be reprinted
|
||||
when ^L is typed.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int get_buf (buf, buf_size, break_ch, prompt) char buf[], prompt[];
|
||||
|
||||
{char *p, *q, pbuf[tty_output_buffer_size];
|
||||
int i, c, j;
|
||||
|
||||
if (tty_input_channel<0) tyiopn ();
|
||||
if (!prompt[0]) /* no explicit prompt */
|
||||
{if (tty_output_count > 0) /* use partial output line */
|
||||
{tty_output_buffer[tty_output_count] = 0;
|
||||
stcpy (tty_output_buffer, pbuf);
|
||||
prompt = pbuf;
|
||||
}
|
||||
else if (tty_default_prompt) /* use default */
|
||||
prompt = tty_default_prompt;
|
||||
}
|
||||
if (prompt != pbuf) tyos (prompt);
|
||||
if (tty_output_count > 0) tyo_flush ();
|
||||
p = buf;
|
||||
i = 0; /* number of chars in buffer */
|
||||
|
||||
while (TRUE)
|
||||
{c = uiiot (tty_input_channel);
|
||||
if (c != break_ch) switch (c) {
|
||||
|
||||
case 0177: /* rubout - delete prev char */
|
||||
|
||||
if (i>0)
|
||||
{c = *--p;
|
||||
--i;
|
||||
if (tty_device_code==2) /* display */
|
||||
{if (c=='\r')
|
||||
{spctty ('U');
|
||||
q = p;
|
||||
while ((c = *--q) != '\r' &&
|
||||
q>=buf)
|
||||
{j = ctrlch(c);
|
||||
while (--j>=0) spctty ('F');
|
||||
}
|
||||
if (q<buf)
|
||||
{q = prompt;
|
||||
while (*q) ++q;
|
||||
while ((c = *--q) != '\n' &&
|
||||
q>=prompt)
|
||||
{j = ctrlch(c);
|
||||
while (--j>=0) spctty ('F');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{j = ctrlch(c);
|
||||
while (--j>=0) spctty ('X');
|
||||
}
|
||||
}
|
||||
else utyo (c);
|
||||
}
|
||||
continue;
|
||||
|
||||
case '\p': /* redisplay buffer */
|
||||
|
||||
*p = 0;
|
||||
(*ttynp) (tty_device_code==2, prompt, buf);
|
||||
continue;
|
||||
|
||||
case 0: /* simulate end-of-file */
|
||||
|
||||
q = buf;
|
||||
while (q < p) {if (*q == '\r') *q = '\n'; ++q;}
|
||||
return (i);
|
||||
|
||||
case '\n': /* ignore - dont want to echo it */
|
||||
|
||||
continue;
|
||||
|
||||
default: if (i <= buf_size - 2)
|
||||
{++i;
|
||||
utyo (*p++ = c);
|
||||
}
|
||||
else utyo (07); /* beep */
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
utyo ('\r');
|
||||
*p++ = c;
|
||||
q = buf;
|
||||
while (q < p) {if (*q == '\r') *q = '\n'; ++q;}
|
||||
return (i+1);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
TTXNP - Default TTY ^L handler
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
ttxnp (display, prompt, buf)
|
||||
int display;
|
||||
char *prompt, *buf;
|
||||
|
||||
{if (display) spctty ('C'); else tyo ('\r');
|
||||
tyos (prompt);
|
||||
tyos (buf);
|
||||
tyo_flush ();
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
TTYIH - TTY Input Interrupt Handler
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
ttyih ()
|
||||
|
||||
{int c;
|
||||
|
||||
c = ityic (tty_input_channel);
|
||||
if (c == 023) signal (ctrls_interrupt);
|
||||
else if (c == 007) signal (ctrlg_interrupt);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
TYIOPN - Open TTY for INPUT.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
channel tyiopn()
|
||||
|
||||
{int block[3];
|
||||
if (tty_input_channel < 0)
|
||||
tty_input_channel = fopen ("/tty", 0);
|
||||
on (ttyi_interrupt, ttyih);
|
||||
ttyget (tty_input_channel, block);
|
||||
block[0] = 020202020202;
|
||||
block[1] = 030202020202;
|
||||
ttyset (tty_input_channel, block);
|
||||
tty_device_code = status (tty_input_channel) & 077;
|
||||
return (tty_input_channel);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
TYOOPN - Open TTY for OUTPUT.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
channel tyoopn()
|
||||
|
||||
{int i;
|
||||
if (tty_output_channel < 0)
|
||||
{tty_output_channel = fopen ("/tty", 021);
|
||||
i = tty_output_buffer;
|
||||
i =| 0444400000000;
|
||||
tty_output_bptr = i;
|
||||
}
|
||||
return (tty_output_channel);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
CTRLCH - Return the number of characters a character
|
||||
prints as.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int ctrlch (c)
|
||||
|
||||
{if (c==0177) return (2);
|
||||
if (c>=' ' || c==033 || c=='\t') return (1);
|
||||
if (c=='\b' || c==07) return (0);
|
||||
return (2);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
SETPROMPT - Set Default Input Prompt String
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
setprompt (s)
|
||||
char *s;
|
||||
|
||||
{tty_default_prompt = s;}
|
||||
216
src/clib/cfloat.cmid
Normal file
216
src/clib/cfloat.cmid
Normal file
@@ -0,0 +1,216 @@
|
||||
;
|
||||
; CFLOAT - FLOATING POINT STUFF
|
||||
;
|
||||
; This file is PDP-10 dependent, system-independent.
|
||||
;
|
||||
|
||||
TITLE CFLOAT
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
; CONTAINS: LOG, EXP, COS, SIN, ATAN, SQRT, DTRUNCATE, DROUND, DABS
|
||||
|
||||
CENTRY LOG,[V]
|
||||
|
||||
MOVE B,V
|
||||
JUMPLE B,OUTRNG
|
||||
LDB D,[331100,,B] ;GRAB EXPONENT
|
||||
SUBI D,201 ;REMOVE BIAS
|
||||
TLZ B,777000 ;SET EXPONENT
|
||||
TLO B,201000 ; TO 1
|
||||
MOVE A,B
|
||||
FSBR A,SQRT2
|
||||
FADR B,SQRT2
|
||||
FDVB A,B
|
||||
FMPR B,B
|
||||
MOVE C,[0.434259751]
|
||||
FMPR C,B
|
||||
FADR C,[0.576584342]
|
||||
FMPR C,B
|
||||
FADR C,[0.961800762]
|
||||
FMPR C,B
|
||||
FADR C,[2.88539007]
|
||||
FMPR C,A
|
||||
FADR C,[0.5]
|
||||
MOVE B,D
|
||||
FSC B,233
|
||||
FADR B,C
|
||||
FMPR B,[0.693147180] ;LOG E OF 2
|
||||
MOVE A,B
|
||||
RETURN
|
||||
|
||||
CENTRY EXP,[V]
|
||||
|
||||
MOVE B,V
|
||||
PUSH P,B
|
||||
MOVM A,B
|
||||
SETZM B
|
||||
FMPR A,[0.434294481] ;LOG BASE 10 OF E
|
||||
MOVE D,[1.0]
|
||||
CAMG A,D
|
||||
GO RATEX
|
||||
MULI A,400
|
||||
ASHC B,-243(A)
|
||||
CAILE B,43
|
||||
GO OUTRNG
|
||||
CAILE B,7
|
||||
GO EXPR2
|
||||
EXPR1: FMPR D,FLOAP1(B)
|
||||
LDB A,[103300,,C]
|
||||
SKIPE A
|
||||
TLO A,177000
|
||||
FADR A,A
|
||||
RATEX: MOVEI B,7
|
||||
SETZM C
|
||||
RATEY: FADR C,COEF2-1(B)
|
||||
FMPR C,A
|
||||
SOJN B,RATEY
|
||||
FADR C,[1.0]
|
||||
FMPR C,C
|
||||
FMPR D,C
|
||||
MOVE B,[1.0]
|
||||
SKIPL (P) ;SKIP IF INPUT NEGATIVE
|
||||
SKIPN B,D
|
||||
FDVR B,D
|
||||
MOVE A,B
|
||||
SUB P,[1,,1]
|
||||
RETURN
|
||||
|
||||
EXPR2: LDB D,[030300,,B]
|
||||
ANDI B,7
|
||||
MOVE D,FLOAP1(D)
|
||||
FMPR D,D ;TO THE 8TH POWER
|
||||
FMPR D,D
|
||||
FMPR D,D
|
||||
GO EXPR1
|
||||
|
||||
COEF2: 1.15129278
|
||||
0.662730884
|
||||
0.254393575
|
||||
0.0729517367
|
||||
0.0174211199
|
||||
2.55491796^-3
|
||||
9.3264267^-4
|
||||
|
||||
FLOAP1: 1.0
|
||||
10.0
|
||||
100.0
|
||||
1000.0
|
||||
10000.0
|
||||
100000.0
|
||||
1000000.0
|
||||
10000000.0
|
||||
|
||||
OUTRNG: CROAK [ARGUMENT OUT OF RANGE]
|
||||
GO RTN1
|
||||
|
||||
CENTRY COS,[V]
|
||||
|
||||
MOVE B,V
|
||||
FADR B,[1.570796326] ;COS(X)=SIN (X+PI/2)
|
||||
CALL SIN,[B]
|
||||
RTN1: RETURN
|
||||
|
||||
CENTRY SIN,[V]
|
||||
|
||||
MOVE B,V
|
||||
CL .SIN
|
||||
RETURN
|
||||
|
||||
.SIN: MOVM A,B
|
||||
CAMG A,[.0001]
|
||||
RTN ;GOSPER'S RECURSIVE SIN.
|
||||
FDVR B,[-3.0] ;SIN(X)=4*SIN(X/-3)**3-3*SIN(X/-3)
|
||||
CL .SIN
|
||||
FSC A,1
|
||||
FMPR A,A
|
||||
FADR A,[-3.0]
|
||||
FMPRB A,B
|
||||
RTN
|
||||
|
||||
CENTRY SQRT,[V]
|
||||
|
||||
MOVE B,V
|
||||
MOVE A,B
|
||||
ASH B,-1
|
||||
FSC B,100
|
||||
SQ2: MOVE C,B ;NEWTON'S METHOD, SPECINER'S HACK.
|
||||
FDVRM A,B
|
||||
FADRM C,B
|
||||
FSC B,-1
|
||||
CAME C,B
|
||||
GO SQ2
|
||||
MOVE A,B
|
||||
RETURN
|
||||
|
||||
CENTRY ATAN,[V],[TEMP]
|
||||
|
||||
MOVE B,V
|
||||
MOVEM B,TEMP
|
||||
MOVM D,B
|
||||
CAMG D,[0.4^-8] ;SMALL ENOUGH SO ATAN(X)=X?
|
||||
GO ATAN3 ;YES
|
||||
CAML D,[7.0^7] ;LARGE ENOUGH SO THAT ATAN(X)=PI/2?
|
||||
GO ATAN1 ;YES
|
||||
MOVN C,[1.0]
|
||||
CAMLE D,[1.0] ;IS ABS(X)<1.0?
|
||||
FDVM C,D ;NO,SCALE IT DOWN
|
||||
MOVE B,D
|
||||
FMPR B,B
|
||||
MOVE C,[1.44863154]
|
||||
FADR C,B
|
||||
MOVE A,[-0.264768620]
|
||||
FDVM A,C
|
||||
FADR C,B
|
||||
FADR C,[3.31633543]
|
||||
MOVE A,[-7.10676005]
|
||||
FDVM A,C
|
||||
FADR C,B
|
||||
FADR C,[6.76213924]
|
||||
MOVE B,[3.70925626]
|
||||
FDVR B,C
|
||||
FADR B,[0.174655439]
|
||||
FMPR B,D
|
||||
JUMPG D,ATAN2 ;WAS ARG SCALED?
|
||||
FADR B,PI2 ;YES, ATAN(X)=PI/2-ATAN(1/X)
|
||||
GO ATAN2
|
||||
ATAN1: MOVE B,PI2
|
||||
ATAN2: SKIPGE TEMP ;WAS INPUT NEGATIVE?
|
||||
MOVNS B ;YES,COMPLEMENT
|
||||
ATAN3: MOVE A,B
|
||||
RETURN
|
||||
|
||||
SQRT2: 1.41421356
|
||||
PI2: 3.1415926535/2
|
||||
|
||||
CENTRY DROUND,[V]
|
||||
|
||||
MOVE A,V
|
||||
FADR A,[.499999]
|
||||
JUMPL A,ROUND1
|
||||
UFA A,[233000000000]
|
||||
TLZ B,777000
|
||||
GO ROUND2
|
||||
ROUND1: UFA A,[233000000000]
|
||||
TLO B,777000
|
||||
ROUND2: MOVE A,B
|
||||
RETURN
|
||||
|
||||
CENTRY DTRUNCATE,[V]
|
||||
|
||||
MOVE A,V
|
||||
UFA A,[233000000000]
|
||||
TLZ B,777000
|
||||
MOVE A,B
|
||||
RETURN
|
||||
|
||||
CENTRY DABS,[V]
|
||||
|
||||
MOVE A,V
|
||||
JUMPGE A,RET
|
||||
MOVN A,A
|
||||
JUMPGE A,RET
|
||||
TLZ A,400000
|
||||
RET: RETURN
|
||||
|
||||
END
|
||||
15
src/clib/clib.h
Normal file
15
src/clib/clib.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/* Handy definitions */
|
||||
|
||||
#define OPENLOSS (-1) /* Returned by COPEN if open fails */
|
||||
|
||||
typedef int SIXBIT; /* Six characters packed in one word */
|
||||
|
||||
typedef struct { /* ITS filespec in sixbit */
|
||||
SIXBIT dev, /* Device */
|
||||
fn1, /* First filename */
|
||||
fn2, /* Second filename */
|
||||
dir; /* Directory */
|
||||
} FILESPEC;
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
47
src/clib/clib.prglst
Normal file
47
src/clib/clib.prglst
Normal file
@@ -0,0 +1,47 @@
|
||||
; CLIB PRGLST
|
||||
; *ITS*
|
||||
|
||||
; This file is a Stinkr XFILE that lists the program files that make up the
|
||||
; shared C library. It is used in the construction of a new library. It
|
||||
; is also used to construct test versions of programs not using the shared
|
||||
; library and to construct timing versions of programs (which cannot use
|
||||
; the shared library).
|
||||
|
||||
; The following are ITS- dependent files from C10LIB:
|
||||
|
||||
l clib;c10cor
|
||||
l clib;c10exp
|
||||
l clib;c10fd
|
||||
l clib;c10fil
|
||||
l clib;c10fnm
|
||||
l clib;c10fo
|
||||
l clib;c10int
|
||||
l clib;c10io
|
||||
l clib;c10map
|
||||
l clib;c10mio
|
||||
l clib;c10pag
|
||||
l clib;c10sys
|
||||
l clib;c10tty
|
||||
|
||||
; The following are ITS-independent files from CLIB:
|
||||
|
||||
l clib;ac
|
||||
l clib;alloc
|
||||
l clib;apfnam
|
||||
l clib;atoi
|
||||
l clib;blt
|
||||
l clib;cfloat
|
||||
l clib;cprint
|
||||
l clib;date
|
||||
l clib;fprint
|
||||
l clib;match
|
||||
l clib;pr60th
|
||||
l clib;random
|
||||
l clib;stkdmp
|
||||
l clib;string
|
||||
l clib;uuoh
|
||||
|
||||
; This must be last:
|
||||
|
||||
l clib;c10run
|
||||
|
||||
15
src/clib/clib.tester
Normal file
15
src/clib/clib.tester
Normal file
@@ -0,0 +1,15 @@
|
||||
; CLIB TESTER
|
||||
; *ITS*
|
||||
|
||||
; This file is a Stinkr XFILE to be used to construct test versions of
|
||||
; programs that do not use the shared C library. Construction of such
|
||||
; programs is useful to test changes to library routines prior to the
|
||||
; construction of a new version of the library.
|
||||
|
||||
; This file must be XFILEd first.
|
||||
; Segment 0 must start at 100.
|
||||
|
||||
s 100,n,p,n
|
||||
i linit
|
||||
|
||||
x c;clib prglst
|
||||
17
src/clib/clib.timer
Normal file
17
src/clib/clib.timer
Normal file
@@ -0,0 +1,17 @@
|
||||
; CLIB TIMER
|
||||
; *ITS*
|
||||
|
||||
; This file is a Stinkr XFILE to be used to construct timing versions of
|
||||
; programs. The only difference from normal programs is that a different
|
||||
; handler is used for the procedure call UUOs.
|
||||
|
||||
; This file must be XFILEd first.
|
||||
; Segment 0 must start at 100.
|
||||
|
||||
s 100,100000,400000,600000
|
||||
i tinit
|
||||
|
||||
l clib;c10tmr
|
||||
l clib;c10tpr
|
||||
|
||||
x clib;clib prglst
|
||||
176
src/clib/cprint.c
Normal file
176
src/clib/cprint.c
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
|
||||
CPRINT - C Formatted Print Routine
|
||||
|
||||
Extendable Format Version:
|
||||
Print Routines should expect the following
|
||||
arguments (n specified when defined):
|
||||
1 to n: n data arguments
|
||||
n+1: file descriptor
|
||||
n+2: field width (0 if none given)
|
||||
|
||||
*/
|
||||
|
||||
# define WORDMASK 077777777777
|
||||
# define SMALLEST "-34359738368"
|
||||
|
||||
extern int cin, cout, cerr;
|
||||
int prc(), prd(), pro(), prs();
|
||||
|
||||
static int (*format_table[26]) () {
|
||||
/* a */ 0, 0, prc, prd, 0, 0, 0, 0,
|
||||
/* i */ 0, 0, 0, 0, 0, 0, pro, 0,
|
||||
/* q */ 0, 0, prs, 0, 0, 0, 0, 0,
|
||||
/* y */ 0, 0};
|
||||
|
||||
static int format_nargs [26] {
|
||||
/* a */ 0, 0, 1, 1, 0, 0, 0, 0,
|
||||
/* i */ 0, 0, 0, 0, 0, 0, 1, 0,
|
||||
/* q */ 0, 0, 1, 0, 0, 0, 0, 0,
|
||||
/* y */ 0, 0};
|
||||
|
||||
deffmt (c, p, n) int (*p)();
|
||||
|
||||
{if (c >= 'A' && c <= 'Z') c =+ ('a' - 'A');
|
||||
if (c >= 'a' && c <= 'z')
|
||||
{if (n >= 0 && n <= 3)
|
||||
{format_table [c - 'a'] = p;
|
||||
format_nargs [c - 'a'] = n;
|
||||
}
|
||||
else cprint (cerr, "bad nargs to DEFFMT: %d\n", n);
|
||||
}
|
||||
else cprint (cerr, "bad character to DEFFMT: %c\n", c);
|
||||
}
|
||||
|
||||
cprint (a1,a2,a3,a4,a5,a6,a7,a8)
|
||||
|
||||
{int *adx, c, width;
|
||||
char *fmt;
|
||||
int fn, (*p)(), n;
|
||||
|
||||
if (cisfd(a1)) /* file descriptor */
|
||||
{fn = a1;
|
||||
fmt = a2;
|
||||
adx = &a3;
|
||||
}
|
||||
else
|
||||
{fn = cout;
|
||||
fmt = a1;
|
||||
adx = &a2;
|
||||
}
|
||||
|
||||
while (c= *fmt++)
|
||||
|
||||
{if (c!='%') cputc (c,fn);
|
||||
else
|
||||
{width = 0;
|
||||
while ((c = *fmt)>='0' && c<='9')
|
||||
width = (width*10) + (*fmt++ - '0');
|
||||
c = *fmt++;
|
||||
if (c >= 'A' && c <= 'Z') c =+ ('a' - 'A');
|
||||
if (c >= 'a' && c <= 'z')
|
||||
{p = format_table [c - 'a'];
|
||||
n = format_nargs [c - 'a'];
|
||||
if (p)
|
||||
{switch (n) {
|
||||
case 0: (*p) (fn, width); break;
|
||||
case 1: (*p) (adx[0], fn, width); break;
|
||||
case 2: (*p) (adx[0], adx[1], fn, width); break;
|
||||
case 3: (*p) (adx[0], adx[1], adx[2], fn, width); break;
|
||||
}
|
||||
adx =+ n;
|
||||
continue;
|
||||
}
|
||||
cputc (c, fn);
|
||||
}
|
||||
else cputc (c, fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PRO - Print Octal Integer
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
pro (i, f, w)
|
||||
|
||||
{int b[30], *p, a;
|
||||
|
||||
if (!cisfd(f)) f = cout;
|
||||
if (w<0 || w>200) w = 0;
|
||||
p = b;
|
||||
while (a = ((i>>3) & WORDMASK))
|
||||
{*p++ = (i&07) + '0';
|
||||
i = a;
|
||||
}
|
||||
*p++ = i+'0';
|
||||
if (i) *p++ = '0';
|
||||
i = w - (p-b);
|
||||
while (--i>=0) cputc (' ', f);
|
||||
while (p > b) cputc (*--p, f);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PRD - Print Decimal Integer
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
prd (i, f, w)
|
||||
|
||||
{int b[30], *p, a, flag;
|
||||
|
||||
flag = 0;
|
||||
if (!cisfd(f)) f = cout;
|
||||
if (w<0 || w>200) w = 0;
|
||||
p = b;
|
||||
if (i < 0) {i = -i; flag = 1;}
|
||||
if (i < 0) {stcpy (SMALLEST, b); p = b+slen(b); flag = 0;}
|
||||
else
|
||||
{while (a = i/10)
|
||||
{*p++ = i%10 + '0';
|
||||
i = a;
|
||||
}
|
||||
*p++ = i+'0';
|
||||
}
|
||||
if (flag) *p++ = '-';
|
||||
i = w - (p-b);
|
||||
while (--i>=0) cputc (' ', f);
|
||||
while (p > b) cputc (*--p, f);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PRS - Print String
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
prs (s, f, w) char *s;
|
||||
|
||||
{int i;
|
||||
|
||||
if (!cisfd(f)) f = cout;
|
||||
if (w<0 || w>200) w = 0;
|
||||
i = (w > 0 ? w - slen (s) : 0);
|
||||
while (--i >= 0) cputc (' ', f);
|
||||
while (i = *s++) cputc (i, f);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PRC - Print Character
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
prc (c, f, w)
|
||||
|
||||
{int i;
|
||||
|
||||
if (!cisfd(f)) f = cout;
|
||||
if (w<0 || w>200) w = 0;
|
||||
i = w - 1;
|
||||
while (--i >= 0) cputc (' ', f);
|
||||
cputc (c, f);
|
||||
}
|
||||
39
src/clib/crate.10
Normal file
39
src/clib/crate.10
Normal file
@@ -0,0 +1,39 @@
|
||||
TITLE CRATE C LIBRARY DESECRATOR FOR VERSION 10
|
||||
A==1
|
||||
GO==JRST
|
||||
|
||||
.GLOBAL INIT,PAGENO,NPAGES,VERNAM
|
||||
INIT: .VALUE [ASCIZ/: INITIALIZE IF NOT FOR VERSION 10
|
||||
/]
|
||||
.CALL [SETZ
|
||||
SIXBIT/OPEN/
|
||||
1000,,1 ; CHANNEL 1
|
||||
[SIXBIT/DSK/]
|
||||
[SIXBIT/[CLIB]/]
|
||||
VERNAM
|
||||
SETZ [SIXBIT/C/]
|
||||
]
|
||||
.VALUE [ASCIZ/: UNABLE TO GET LIBRARY FILE
|
||||
/]
|
||||
MOVN A,NPAGES
|
||||
HRLZ A,A
|
||||
HRR A,PAGENO
|
||||
.CALL [SETZ
|
||||
'CORBLK
|
||||
1000,,600000 ; READ-WRITE ACCESS
|
||||
1000,,-1 ; PUT IN MY MAP
|
||||
A ; AOBJN POINTER
|
||||
401000,,1 ; FROM FILE
|
||||
]
|
||||
.VALUE [ASCIZ/: UNABLE TO MAP IN LIBRARY FILE
|
||||
/]
|
||||
.CLOSE 1,
|
||||
.VALUE [ASCIZ/: ALL SET
|
||||
:SL /]
|
||||
GO .-1
|
||||
|
||||
PAGENO: 246. ; FIRST PAGE TO SMASH
|
||||
NPAGES: 10. ; NUMBER OF PAGES TO SMASH
|
||||
VERNAM: SIXBIT/10/ ; VERSION NUMBER IN SIXBIT
|
||||
|
||||
END INIT
|
||||
16
src/clib/ctype.c
Normal file
16
src/clib/ctype.c
Normal file
@@ -0,0 +1,16 @@
|
||||
# include "ctype.h"
|
||||
|
||||
# define S _S
|
||||
# define N _N
|
||||
# define L _L
|
||||
# define U _U
|
||||
|
||||
char _ctype[] {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
N, N, N, N, N, N, N, N, N, N, 0, 0, 0, 0, 0, 0,
|
||||
0, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U,
|
||||
U, U, U, U, U, U, U, U, U, U, U, 0, 0, 0, 0, 0,
|
||||
0, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,
|
||||
L, L, L, L, L, L, L, L, L, L, L, 0, 0, 0, 0, 0};
|
||||
154
src/clib/date.c
Normal file
154
src/clib/date.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
|
||||
DATE - Date Hacking Routines
|
||||
|
||||
These routines recognize three representations for dates:
|
||||
|
||||
(1) CAL - calender date, a system-independent representation
|
||||
consisting of a record containing six integers
|
||||
for the year, month, day, hour, minute, and second
|
||||
|
||||
(2) FDATE - the ITS date representation used in file directories
|
||||
|
||||
(3) UDATE - the UNIX date representation, seconds since
|
||||
Jan 1, 1970, GMT.
|
||||
|
||||
(4) TDATE - the TOPS-20 date representation
|
||||
|
||||
The routines:
|
||||
|
||||
u2cal (udate, cd) - convert udate to cal
|
||||
udate = cal2u (cd) - convert cal to udate
|
||||
f2cal (fdate, cd) - convert fdate to cal
|
||||
fdate = cal2f (cd) - convert cal to fdate
|
||||
t2cal (tdate, cd)
|
||||
tdate = cal2t (cd)
|
||||
prcal (cd, fd) - print cal (CIO)
|
||||
|
||||
|
||||
*/
|
||||
|
||||
# define ZONE 5 /* offset of local zone from GMT */
|
||||
struct _cal {int year, month, day, hour, minute, second;};
|
||||
# define cal struct _cal
|
||||
|
||||
static int month_tab1[] {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
|
||||
static int month_tab2[] {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
|
||||
static int year_tab[] {0, 365, 2*365, 3*365+1};
|
||||
|
||||
# define four_years (4*365+1)
|
||||
|
||||
static char *month_name[] {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
|
||||
# rename srctab "SRCTAB"
|
||||
|
||||
u2cal (udate, cd) cal *cd;
|
||||
|
||||
{udate =- (ZONE*60*60);
|
||||
cd->second = udate%60; udate =/ 60;
|
||||
cd->minute = udate%60; udate =/ 60;
|
||||
cd->hour = udate%24; udate =/ 24;
|
||||
cd->year = 1970 + 4*(udate/four_years);
|
||||
udate =% four_years;
|
||||
cd->year =+ srctab (year_tab, 4, &udate);
|
||||
cd->month = srctab (cd->year%4==0 ? month_tab2 : month_tab1,
|
||||
12, &udate) + 1;
|
||||
cd->day = udate + 1;
|
||||
}
|
||||
|
||||
int cal2u (cd) cal *cd;
|
||||
|
||||
{int udate, year;
|
||||
|
||||
year = cd->year;
|
||||
udate = cd->second + 60*(cd->minute + 60*(cd->hour + 24*(cd->day-1)));
|
||||
udate =+ (year%4==0 ? month_tab2 : month_tab1) [cd->month-1] * 60*60*24;
|
||||
year =- 1970;
|
||||
if (year<0) year=0;
|
||||
udate =+ 60*60*24*(four_years*(year/4) + year_tab[year%4]);
|
||||
udate =+ (ZONE*60*60);
|
||||
return (udate);
|
||||
}
|
||||
|
||||
f2cal (fdate, cd) cal *cd;
|
||||
|
||||
{cd->year = 1900 + ((fdate>>27) & 0177);
|
||||
if ((cd->month = (fdate>>23) & 017) > 12) cd->month = 0;
|
||||
cd->day = (fdate>>18) & 037;
|
||||
fdate = (fdate & 0777777) >> 1;
|
||||
cd->second = fdate % 60;
|
||||
fdate =/ 60;
|
||||
cd->minute = fdate % 60;
|
||||
cd->hour = fdate / 60;
|
||||
}
|
||||
|
||||
int cal2f (cd) cal *cd;
|
||||
|
||||
{int fdate;
|
||||
|
||||
fdate = 2*(cd->second + 60*(cd->minute + 60*cd->hour));
|
||||
fdate =| cd->day << 18;
|
||||
fdate =| cd->month << 23;
|
||||
fdate =| (cd->year - 1900) << 27;
|
||||
return (fdate);
|
||||
}
|
||||
|
||||
t2cal (tdate, cd) cal *cd;
|
||||
|
||||
{int vec[3], udate;
|
||||
SYSODCNV (tdate, 0, vec);
|
||||
cd->year = vec[0] >> 18;
|
||||
cd->month = (vec[0] & 0777777) + 1;
|
||||
cd->day = (vec[1] >> 18) + 1;
|
||||
udate = vec[2] & 0777777;
|
||||
cd->second = udate%60; udate =/ 60;
|
||||
cd->minute = udate%60; udate =/ 60;
|
||||
cd->hour = udate%24;
|
||||
}
|
||||
|
||||
int cal2t (cd) cal *cd;
|
||||
|
||||
{char buf[100];
|
||||
int f;
|
||||
f = copen (buf, 'w', "s");
|
||||
cprint (f, "%d/%d/%d %d:%d:%d", cd->month, cd->day, cd->year,
|
||||
cd->hour, cd->minute, cd->second);
|
||||
cclose (f);
|
||||
return (SYSIDTIM (mkbptr (buf), 0));
|
||||
}
|
||||
|
||||
prcal (cd, f) cal *cd;
|
||||
|
||||
{char *s;
|
||||
int m;
|
||||
m = cd->month-1;
|
||||
if (m>=0 && m<=11) s = month_name[m];
|
||||
else s = "?";
|
||||
cprint (f, "%s%3d%5d ", s, cd->day, cd->year);
|
||||
cputc (cd->hour/10+'0', f);
|
||||
cputc (cd->hour%10+'0', f);
|
||||
cputc (':', f);
|
||||
cputc (cd->minute/10+'0', f);
|
||||
cputc (cd->minute%10+'0', f);
|
||||
cputc (':', f);
|
||||
cputc (cd->second/10+'0', f);
|
||||
cputc (cd->second%10+'0', f);
|
||||
}
|
||||
|
||||
int srctab (tab, sz, n) int *tab, sz, *n;
|
||||
|
||||
{int *p, i;
|
||||
|
||||
p = tab+sz;
|
||||
i = *n;
|
||||
|
||||
while (--p>=tab)
|
||||
{if (*p <= i)
|
||||
{*n = i - *p;
|
||||
return (p-tab);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
89
src/clib/fprint.c
Normal file
89
src/clib/fprint.c
Normal file
@@ -0,0 +1,89 @@
|
||||
#
|
||||
|
||||
/*
|
||||
*
|
||||
* FPRINT - Floating-Point Print Routine
|
||||
*
|
||||
* requires:
|
||||
*
|
||||
* i = dtruncate (d)
|
||||
* i = dround (d)
|
||||
* d = dabs (d)
|
||||
* cputc (c, fd)
|
||||
*
|
||||
* internal routines and tables:
|
||||
*
|
||||
* fp3, fp4, fp5, fp6, ft0, ft1, ft10
|
||||
*
|
||||
*/
|
||||
|
||||
static double ft0[] {1e1, 1e2, 1e4, 1e8, 1e16, 1e32};
|
||||
static double ft1[] {1e-1, 1e-2, 1e-4, 1e-8, 1e-16, 1e-32};
|
||||
static double ft10[] {1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7};
|
||||
double dabs ();
|
||||
|
||||
fprint (d, fd)
|
||||
double d;
|
||||
|
||||
{if (d<0) {cputc ('-', fd); d = dabs (d);}
|
||||
if (d>0)
|
||||
{if (d < 1.0) {fp4 (d, 0, fd); return;}
|
||||
else if (d >= 1e8) {fp4 (d, 1, fd); return;}
|
||||
}
|
||||
fp3 (d, fd);
|
||||
}
|
||||
|
||||
fp3 (d, fd) /* print positive double */
|
||||
double d;
|
||||
|
||||
{int i, n;
|
||||
double fraction;
|
||||
|
||||
i = dtruncate (d);
|
||||
fraction = d - i;
|
||||
n = fp5 (i, fd); /* return # of digits printed */
|
||||
cputc ('.', fd);
|
||||
n = 8 - n;
|
||||
fraction =* ft10[n];
|
||||
i = dround (fraction);
|
||||
fp6 (i, n, fd); /* prints n digits */
|
||||
}
|
||||
|
||||
fp4 (d, flag, fd)
|
||||
double d;
|
||||
|
||||
{int c, e;
|
||||
|
||||
c = 6;
|
||||
e = 0;
|
||||
while (--c >= 0)
|
||||
{e =<< 1;
|
||||
if (flag ? d >= ft0[c] : d <= ft1[c])
|
||||
{++e;
|
||||
d =* (flag ? ft1[c] : ft0[c]);
|
||||
}
|
||||
}
|
||||
if (d < 1.0) {++e; d =* 10.0;}
|
||||
fp3 (d, fd);
|
||||
cputc ('e', fd);
|
||||
cputc (flag ? '+' : '-', fd);
|
||||
fp5 (e, fd);
|
||||
}
|
||||
|
||||
int fp5 (i, fd) /* print decimal integer, return # of digits printed */
|
||||
|
||||
{int a;
|
||||
|
||||
if (a = i/10) a = fp5 (a, fd);
|
||||
else a = 0;
|
||||
cputc (i%10 + '0', fd);
|
||||
return (a+1);
|
||||
}
|
||||
|
||||
int fp6 (i, n, fd) /* print decimal integer given # of digits */
|
||||
|
||||
{if (n>0)
|
||||
{if (n>1) fp6 (i/10, n-1, fd);
|
||||
cputc (i%10 + '0', fd);
|
||||
}
|
||||
}
|
||||
78
src/clib/getsrv.c
Normal file
78
src/clib/getsrv.c
Normal file
@@ -0,0 +1,78 @@
|
||||
# include "c.defs"
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
GETSRV - Lookup name in table of Arpanet Servers
|
||||
Currently runs only on ITS machines (needs a particular file).
|
||||
Requires upper case string.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
# define TABLESIZE 10000
|
||||
|
||||
int getsrv (s) char *s; /* return -1 if bad */
|
||||
|
||||
{static int *p;
|
||||
int n, *nmtab;
|
||||
/* first check for decimal host number */
|
||||
n = atoi (s);
|
||||
if (n > 0) return (n);
|
||||
/* if not a number, must search the table of host names */
|
||||
if (!p) /* host file not read in yet */
|
||||
{int f, *q, *e;
|
||||
char *ss;
|
||||
p = calloc (TABLESIZE);
|
||||
ss = "sysbin;hosts1 >";
|
||||
f = copen (ss, 'r', "b");
|
||||
if (f == OPENLOSS)
|
||||
{cprint ("Unable to find host table: %s\n", ss);
|
||||
return (-1);
|
||||
}
|
||||
e = p + TABLESIZE;
|
||||
q = p;
|
||||
while (!ceof (f) && q<e) *q++ = cgeti (f);
|
||||
cclose (f);
|
||||
}
|
||||
nmtab = p+p[6]; /* name table */
|
||||
n = *nmtab++;
|
||||
while (--n >= 0)
|
||||
{int nte, nm, bp;
|
||||
nte = *nmtab++;
|
||||
nm = nte & 0777777; /* index of name in table */
|
||||
nm = p + nm; /* pointer to name in table */
|
||||
bp = 0440700000000 | nm; /* byte pointer to name */
|
||||
if (_gmatch (bp, s)) /* found entry */
|
||||
{int num;
|
||||
num = nte >> 18; /* index of numtab entry in table */
|
||||
if (p[num+2]<0) /* it's a server */
|
||||
return (p[num]);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
_gmatch (bp, s) char *s;
|
||||
|
||||
{int c;
|
||||
while (c = ildb (&bp))
|
||||
if (c != *s++) return (FALSE);
|
||||
return (*s == 0);
|
||||
}
|
||||
|
||||
|
||||
#ifdef testing
|
||||
main ()
|
||||
|
||||
{char buf[100];
|
||||
int n;
|
||||
|
||||
while (TRUE)
|
||||
{cprint ("Enter name:");
|
||||
gets (buf);
|
||||
n = getsrv (buf);
|
||||
cprint ("Name=%s,Number=%d\n", buf, n);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
76
src/clib/its.bits
Normal file
76
src/clib/its.bits
Normal file
@@ -0,0 +1,76 @@
|
||||
/* open modes */
|
||||
|
||||
# define UAI 0 /* unit ascii input */
|
||||
# define UAO 1 /* unit ascii output */
|
||||
# define BAI 2 /* block ascii input */
|
||||
# define BAO 3 /* block ascii output */
|
||||
# define UII 4 /* unit image input */
|
||||
# define UIO 5 /* unit image output */
|
||||
# define BII 6 /* block image input */
|
||||
# define BIO 7 /* block image output */
|
||||
# define OLD 010 /* open old job only */
|
||||
|
||||
/* user variables */
|
||||
|
||||
# define UPC 0
|
||||
# define UTTY 02
|
||||
# define UUNAME 04
|
||||
# define UJNAME 05
|
||||
# define USTOP 07
|
||||
# define UPIRQ 010
|
||||
# define UINF 011
|
||||
# define USV40 013
|
||||
# define UIPIRQ 014
|
||||
# define UAPIRQ 015
|
||||
# define USNAME 016
|
||||
# define UPICLR 017
|
||||
# define URUNT 024
|
||||
# define UHSNAME 043
|
||||
# define UOPTION 054
|
||||
# define USUPPR 065
|
||||
# define UXUNAME 074
|
||||
# define UXJNAME 075
|
||||
|
||||
/* USTOP magic bit */
|
||||
|
||||
# define BUSRC 0100000000000
|
||||
|
||||
/* .OPTION bits */
|
||||
|
||||
# define OPTBRK 020000000000 /* can handle .BREAKs */
|
||||
# define OPTCMD 040000000000 /* got command arg to give */
|
||||
# define OPTOPC 000200000000 /* always reset PC on interrupt */
|
||||
|
||||
/* first word interrupt bits */
|
||||
|
||||
# define PJRLT 0200000000000 /* Real-time timer went off [3] (A) */
|
||||
# define PJRUN 0100000000000 /* Run-time timer went off [3] (A) */
|
||||
# define PJTTY 02000000000 /* Don't have TTY [2] (S) */
|
||||
# define PJPAR 01000000000 /* Memory parity error [1] (A) */
|
||||
# define PJFOV 0400000000 /* ARFOV (Floating overflow) [3] (S) */
|
||||
# define PJWRO 0200000000 /* WIRO (Write in read-only page) [2] (S) */
|
||||
# define PJFET 0100000000 /* Fetched insn from impure page [2] (S) */
|
||||
# define PJTRP 040000000 /* SYSUUO (System uuo in trap mode) [2] (S) */
|
||||
# define PJDBG 02000000 /* System being debugged state change [3] (A) */
|
||||
# define PILOS 01000000 /* .LOSE */
|
||||
# define PICLI 0400000 /* CLI interrupt [3] (A) */
|
||||
# define PIPDL 0200000 /* PDL overflow [3] (S) */
|
||||
# define PILTP 0100000 /* 340 or E&S light pen hit [3] (A) */
|
||||
# define PIMAR 040000 /* MAR hit. [2] (S) */
|
||||
# define PIMPV 020000 /* MPV (memory protect violation) [2] (S) */
|
||||
# define PICLK 010000 /* Slow (1/2 sec) clock [3] (A) */
|
||||
# define PI1PR 04000 /* Single-instruction proceed [1] (S) */
|
||||
# define PIBRK 02000 /* .BREAK instruction executed. [1] (S) */
|
||||
# define PIOOB 01000 /* Address out of bounds [2] (S) */
|
||||
# define PIIOC 0400 /* IOCERR (I/O channel error) [2] (S) */
|
||||
# define PIVAL 0200 /* .VALUE instruction executed [1] (S) */
|
||||
# define PIDWN 0100 /* System-going-down status change [3] (A) */
|
||||
# define PIILO 040 /* ILOPR, ILUUO (illegal operation) [2] (S) */
|
||||
# define PIDIS 020 /* Display memory protect [2] (A) */
|
||||
# define PIARO 010 /* Arithmetic overflow [3] (S) */
|
||||
# define PIB42 04 /* BADPI (Bad location 42) [1] (S) */
|
||||
# define PICZ 02 /* ^Z or CALL typed on terminal [1] (A) */
|
||||
# define PITYI 01 /* TTY input (obsolete) [3] (A) */
|
||||
|
||||
# define IBACKUP (PJTTY|PJWRO|PJFET|PJTRP|PIMPV|PIOOB|PIIOC|PIILO)
|
||||
/* interrupts where PC may need SOSing */
|
||||
282
src/clib/maklib.c
Normal file
282
src/clib/maklib.c
Normal file
@@ -0,0 +1,282 @@
|
||||
# include "c.defs"
|
||||
# include "its.bits"
|
||||
|
||||
/*
|
||||
|
||||
MAKLIB
|
||||
|
||||
*ITS*
|
||||
|
||||
Shared C Library Construction Program
|
||||
|
||||
Loads library stuff from TS CLIB into an inferior. Writes
|
||||
pure part as a sharable file. Constructs a MIDAS program
|
||||
to load the impure part and define all symbols.
|
||||
|
||||
*** Instructions for constructing a new version of the
|
||||
shared C library:
|
||||
|
||||
1. Edit the file MKCLIB STINKR to contain all of the
|
||||
files you want to be in the library. See that file
|
||||
for further instructions.
|
||||
2. Create a TS CLIB in the C directory by running Stinkr on
|
||||
MKCLIB STINKR.
|
||||
3. Create a TS MAKLIB using MAKLIB STINKR.
|
||||
4. Run TS MAKLIB.
|
||||
|
||||
The STINKR files are kept in C10LIB.
|
||||
|
||||
*/
|
||||
|
||||
# define MAXSYMS 4000 /* maximum number of symbols */
|
||||
# define NAMMASK 0037777777777 /* name mask away flags */
|
||||
# define SYMMASK 0037777777777 /* symtab mask for name */
|
||||
|
||||
struct _syment {int sym, val;};
|
||||
typedef struct _syment syment;
|
||||
syment symtab[MAXSYMS];
|
||||
syment *csymp, *esymp;
|
||||
|
||||
main (argc, argv) char *argv[];
|
||||
|
||||
{int flib, fmak, version, nam, val, npage, pgno, zeroc;
|
||||
int j, jch, pch, ilo, ihi, plo, phi, count;
|
||||
char svers[20], buf[50], vbuf[100];
|
||||
filespec ff;
|
||||
syment *p;
|
||||
|
||||
/* open library program file */
|
||||
|
||||
pch = fopen ("TS CLIB", UII);
|
||||
if (pch < 0)
|
||||
{puts ("Unable to find TS CLIB");
|
||||
return;
|
||||
}
|
||||
|
||||
/* create an inferior job */
|
||||
|
||||
j = j_create (020);
|
||||
if (j < 0)
|
||||
{puts ("Unable to create inferior job");
|
||||
return;
|
||||
}
|
||||
|
||||
j_name (j, &ff);
|
||||
jch = open (&ff, UII);
|
||||
if (jch < 0)
|
||||
{puts ("Unable to open inferior job");
|
||||
return;
|
||||
}
|
||||
|
||||
/* load CLIB program into inferior */
|
||||
|
||||
if (sysload (jch, pch))
|
||||
{puts ("Unable to load TS CLIB");
|
||||
return;
|
||||
}
|
||||
rsymtab (pch);
|
||||
|
||||
flib = copen ("c/[clib].>", 'w', "b");
|
||||
if (flib < 0)
|
||||
{puts ("Unable to create library file");
|
||||
return;
|
||||
}
|
||||
filnam (itschan (flib), &ff);
|
||||
version = ff.fn2;
|
||||
c6tos (version, svers);
|
||||
apfname (buf, "c/[cmak].foo", svers);
|
||||
fmak = copen (buf, 'w');
|
||||
if (fmak < 0)
|
||||
{puts ("Unable to create maker file");
|
||||
cclose (flib);
|
||||
delete ("c/clib.>");
|
||||
return;
|
||||
}
|
||||
cprint ("Creating C library version %s\n", svers);
|
||||
cprint (fmak, ";\tSHARED C LIBRARY MAKER -- VERSION %s\n\n", svers);
|
||||
cprint (fmak, ".INSRT C;NC INSERT\n");
|
||||
cprint (fmak, "TITLE CLIB C LIBRARY VERSION %s\n\n", svers);
|
||||
|
||||
p = symtab;
|
||||
while (p < csymp)
|
||||
{nam = p->sym;
|
||||
val = p->val;
|
||||
++p;
|
||||
prname (nam, fmak, 0);
|
||||
cprint (fmak, "\"=%o\n", val);
|
||||
}
|
||||
cputc ('\n', fmak);
|
||||
|
||||
/* now define impure area */
|
||||
|
||||
ilo = jread (lookup (rdname ("SEG0LO")), jch);
|
||||
ihi = jread (lookup (rdname ("SEG1HI")), jch);
|
||||
count = ihi - ilo + 1;
|
||||
|
||||
cprint (fmak, "\t.IDATA\n\n");
|
||||
zeroc = 0;
|
||||
access (jch, ilo);
|
||||
while (--count >= 0)
|
||||
{val = uiiot (jch);
|
||||
if (val)
|
||||
{if (zeroc>0) cprint (fmak, "\tBLOCK\t%o\n", zeroc);
|
||||
zeroc = 0;
|
||||
cprint (fmak, "\t%o\n", val);
|
||||
}
|
||||
else ++zeroc;
|
||||
}
|
||||
if (zeroc>0) cprint (fmak, "\tBLOCK\t%o\n", zeroc);
|
||||
cputc ('\n', fmak);
|
||||
|
||||
plo = jread (lookup (rdname ("SEG2LO")), jch);
|
||||
phi = jread (lookup (rdname ("SEG3HI")), jch);
|
||||
phi =+ 0100;
|
||||
plo =& ~01777;
|
||||
npage = (phi - plo + 02000) >> 10;
|
||||
pgno = plo >> 10;
|
||||
|
||||
cprint (fmak, "IPATCH\": BLOCK 40\n\
|
||||
.CODE\n\
|
||||
INIT\": MOVEI P,ARGV\n\
|
||||
PUSHJ P,MAPIN\"\n\
|
||||
MOVEI A,ZMAIN\"\n\
|
||||
HRRM A,CALLER\"\n\
|
||||
GO START\"\n\n\
|
||||
MAPIN: .CALL [SETZ\n\
|
||||
SIXBIT/OPEN/\n\
|
||||
1000,,1 ; CHANNEL 1\n\
|
||||
[SIXBIT/DSK/]\n\
|
||||
[SIXBIT/[CLIB]/]\n\
|
||||
[SIXBIT/%s/]\n\
|
||||
SETZ [SIXBIT/C/]\n\
|
||||
]\n\
|
||||
.VALUE [ASCIZ/: UNABLE TO GET LIBRARY FILE /]\n\
|
||||
MOVE A,[-%d.,,%o]\n\
|
||||
.CALL [SETZ\n\
|
||||
'CORBLK\n\
|
||||
1000,,200000 ; READ-ONLY\n\
|
||||
1000,,-1 ; PUT IN MY MAP\n\
|
||||
A ; AOBJN POINTER\n\
|
||||
401000,,1 ; FROM FILE\n\
|
||||
]\n\
|
||||
.VALUE [ASCIZ/: UNABLE TO MAP IN LIBRARY FILE /]\n\
|
||||
.CLOSE 1,\n\
|
||||
POPJ P,\n\n\
|
||||
MAPOUT\":MOVE A,[-%d.,,%o]\n\
|
||||
.CALL [SETZ\n\
|
||||
'CORBLK\n\
|
||||
1000,,0 ; DELETE\n\
|
||||
1000,,-1 ; FROM ME\n\
|
||||
400000,,A ; AOBJN POINTER\n\
|
||||
]\n\
|
||||
.VALUE [ASCIZ/: CAN'T MAP OUT LIBRARY PAGES /]\n\
|
||||
POPJ P,\n\n\
|
||||
SINIT\": MOVE A,[PUSHJ P,MAPIN]\n\
|
||||
MOVEM A,ISTART\"\n\
|
||||
MOVE A,[PUSHJ P,MAPOUT]\n\
|
||||
MOVEM A,IDONE\"\n\
|
||||
GO LINIT\"\n\n", svers, npage, pgno, npage, pgno);
|
||||
|
||||
cprint (fmak, ".PDATA\NEND INIT\n");
|
||||
cclose (fmak);
|
||||
|
||||
count = phi - plo + 1;
|
||||
count = (count + 01777) & ~01777;
|
||||
access (jch, plo);
|
||||
while (--count >= 0)
|
||||
{val = uiiot (jch);
|
||||
cputi (val, flib);
|
||||
}
|
||||
cclose (flib);
|
||||
|
||||
fmak = copen (vbuf, 'w', "s");
|
||||
cprint (fmak, ":KILL\r:MIDAS C;[CREL] %s _ C;[CMAK] %s\r", svers, svers);
|
||||
cclose (fmak);
|
||||
valret (vbuf);
|
||||
}
|
||||
|
||||
int jread (loc, jch)
|
||||
|
||||
{access (jch, loc);
|
||||
return (uiiot (jch));
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
SYMBOL TABLE
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
rsymtab (ch)
|
||||
|
||||
{int count;
|
||||
csymp = symtab;
|
||||
esymp = symtab + MAXSYMS;
|
||||
|
||||
uiiot (ch);
|
||||
count = -((uiiot (ch) >> 18) | 0777777000000) / 2;
|
||||
uiiot (ch);
|
||||
uiiot (ch);
|
||||
--count;
|
||||
|
||||
while (--count >= 0)
|
||||
{int n, val;
|
||||
n = uiiot (ch) & SYMMASK;
|
||||
val = uiiot (ch);
|
||||
csymp->sym = n;
|
||||
csymp->val = val;
|
||||
++csymp;
|
||||
}
|
||||
}
|
||||
|
||||
int lookup (sym)
|
||||
|
||||
{syment *p;
|
||||
|
||||
for (p = symtab; p < csymp; ++p)
|
||||
if (p->sym == sym) return (p->val);
|
||||
puts ("symbol missing");
|
||||
return (01000000);
|
||||
}
|
||||
|
||||
char tab40[] {' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
|
||||
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
|
||||
'W', 'X', 'Y', 'Z', '.', '$', '%'};
|
||||
|
||||
rdname (p) char *p;
|
||||
|
||||
{int w, factor, c;
|
||||
char *s;
|
||||
s = p;
|
||||
w = 0;
|
||||
factor = (40*40*40*40*40);
|
||||
while (c = *s++)
|
||||
{int i;
|
||||
if (c==' ') continue;
|
||||
if (factor == 0) continue;
|
||||
if (c>='a' && c<='z') c =+ ('A'-'a');
|
||||
for (i=0;i<40;++i)
|
||||
if (c == tab40[i])
|
||||
{w =+ (i * factor);
|
||||
factor =/ 40;
|
||||
break;
|
||||
}
|
||||
if (i>=40) break;
|
||||
}
|
||||
return (w);
|
||||
}
|
||||
|
||||
prname (n, fn, w)
|
||||
|
||||
{n =& NAMMASK;
|
||||
if (n) p40 (n, fn);
|
||||
}
|
||||
|
||||
p40 (i, fn)
|
||||
|
||||
{int a;
|
||||
if (a = i/40) p40 (a, fn);
|
||||
i =% 40;
|
||||
if (i) cputc (tab40[i], fn);
|
||||
}
|
||||
7
src/clib/maklib.stinkr
Normal file
7
src/clib/maklib.stinkr
Normal file
@@ -0,0 +1,7 @@
|
||||
x clib
|
||||
l maklib
|
||||
l apfnam
|
||||
l c10job
|
||||
l c10fnm
|
||||
o ts maklib
|
||||
|
||||
93
src/clib/match.c
Normal file
93
src/clib/match.c
Normal file
@@ -0,0 +1,93 @@
|
||||
# include "c.defs"
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
SMATCH - pattern matching procedure
|
||||
|
||||
The pattern P is a character string which is to be matched
|
||||
with the data string S. Certain characters in P are treated
|
||||
special:
|
||||
|
||||
'*' match any substring
|
||||
'?' match any character
|
||||
'\\' quote following character
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int smatch (p, s)
|
||||
char *p;
|
||||
char *s;
|
||||
|
||||
{int c1, c2, i;
|
||||
|
||||
while (TRUE)
|
||||
{c1 = *p++;
|
||||
c2 = *s++;
|
||||
switch (c1) {
|
||||
|
||||
case 0: return (!c2);
|
||||
case '?': if (!c2) return (FALSE);
|
||||
continue;
|
||||
case '*': while (*p=='*') ++p;
|
||||
if (*p==0) return (TRUE);
|
||||
i = -1;
|
||||
do if (smatch (p, s+i)) return (TRUE);
|
||||
while (s[i++]);
|
||||
return (FALSE);
|
||||
case '\\': if (!(c1 = *p++)) return (FALSE);
|
||||
/* fall through */
|
||||
default: if (c1 != c2) return (FALSE);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
SINDEX (P, DS)
|
||||
|
||||
Return the index of the first occurrence of the string P
|
||||
in the string DS. Return -1 if P does not occur in DS.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int sindex (p, ds)
|
||||
char *p;
|
||||
char *ds;
|
||||
|
||||
{int c1, c2, start;
|
||||
char *s, *t1, *t2, *tail;
|
||||
|
||||
s = ds;
|
||||
start = p[0];
|
||||
tail = p+1;
|
||||
if (start) while (TRUE)
|
||||
{while ((c2 = *s++) != start)
|
||||
if (c2==0) return (-1);
|
||||
t1 = tail;
|
||||
t2 = s;
|
||||
while ((c1 = *t1++) == (c2 = *t2++))
|
||||
if (c1==0) break;
|
||||
if (c1==0) break;
|
||||
}
|
||||
return (s-ds-1);
|
||||
}
|
||||
|
||||
# ifdef test
|
||||
|
||||
int main ()
|
||||
|
||||
{char buf1[100], buf2[100];
|
||||
|
||||
while (TRUE)
|
||||
{cprint ("Pattern: ");
|
||||
gets (buf1);
|
||||
cprint ("Data: ");
|
||||
gets (buf2);
|
||||
if (smatch (buf1, buf2))
|
||||
cprint ("Matched.\n");
|
||||
else cprint ("No match.\n");
|
||||
}
|
||||
}
|
||||
|
||||
# endif
|
||||
29
src/clib/mkclib.stinkr
Normal file
29
src/clib/mkclib.stinkr
Normal file
@@ -0,0 +1,29 @@
|
||||
; Stinkr xfile for loading basic C library in preparation for construction
|
||||
; of the shared library.
|
||||
|
||||
; note -- it is proper for ZMAIN to be undefined
|
||||
; note -- it is proper for DATE to have 3 TOPS-20-related names undefined
|
||||
|
||||
; The last two addresses in the 's' command must be set so that nothing
|
||||
; overlaps and there is no wraparound. You also have to leave some room
|
||||
; at the end for consing done during loading.
|
||||
|
||||
; The best procedure is to first use 'p' for the last two numbers, which
|
||||
; tells Stinkr to allocate from the next page boundary. Then run Stinkr
|
||||
; to find out how big the segments are. Then you can change the starting
|
||||
; addresses to push the last to segments as close to the end as possible.
|
||||
; You should leave about 400 octal words for cons space; if you have not
|
||||
; left enough, stinker will die saying LBINIT failed.
|
||||
|
||||
; If the library has gotten bigger (more pages), the program C10SAV must
|
||||
; be changed accordingly.
|
||||
|
||||
; C10SRY should not be here; you want to run it before the library is mapped
|
||||
; in.
|
||||
; C10SAV should not be here; it maps out the library as it runs.
|
||||
|
||||
s 100,n,755400,774000
|
||||
i lbinit
|
||||
o ts clib
|
||||
|
||||
x c;clib prglst
|
||||
56
src/clib/pr60th.c
Normal file
56
src/clib/pr60th.c
Normal file
@@ -0,0 +1,56 @@
|
||||
# include "c.defs"
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PR60TH - Print time in 1/60 sec.
|
||||
|
||||
Print time HH:MM:SS.XX on file FILE.
|
||||
TIME is in units of 1/60 sec.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
pr60th (time, file)
|
||||
|
||||
{int ss, sc, mn, hour, zs;
|
||||
|
||||
if (time < 0) time = -time;
|
||||
zs = TRUE;
|
||||
ss = time%60;
|
||||
time = time/60;
|
||||
sc = time%60;
|
||||
time = time/60;
|
||||
mn = time%60;
|
||||
hour = time/60;
|
||||
if (hour)
|
||||
{cprint (file, "%3d:", hour);
|
||||
zs = FALSE;
|
||||
}
|
||||
else cprint (file, " ");
|
||||
xput2 (mn, file, zs);
|
||||
if (zs && mn==0) cputc (' ', file);
|
||||
else
|
||||
{cputc (':', file);
|
||||
zs = FALSE;
|
||||
}
|
||||
if (zs && !sc)
|
||||
{cputc (' ', file);
|
||||
cputc ('0', file);
|
||||
}
|
||||
else
|
||||
{xput2 (sc, file, zs);
|
||||
zs = FALSE;
|
||||
}
|
||||
cputc ('.', file);
|
||||
xput2 (ss, file, FALSE);
|
||||
}
|
||||
|
||||
xput2 (val, file, zs)
|
||||
|
||||
{int num;
|
||||
num = val/10;
|
||||
if (num>0 || !zs) {cputc ('0'+num, file); zs=FALSE;}
|
||||
else cputc (' ', file);
|
||||
num = val%10;
|
||||
if (num>0 || !zs) cputc ('0'+num, file);
|
||||
else cputc (' ', file);
|
||||
}
|
||||
31
src/clib/random.cmid
Normal file
31
src/clib/random.cmid
Normal file
@@ -0,0 +1,31 @@
|
||||
;
|
||||
; RANDOM - RANDOM NUMBER GENERATOR (STOLEN FROM MUDDLE)
|
||||
;
|
||||
; This file is PDP-10 dependent, system-independent.
|
||||
;
|
||||
|
||||
TITLE RANDOM
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
CENTRY SRAND,[SEED]
|
||||
MOVE A,SEED
|
||||
ROT A,-1
|
||||
MOVEM A,RLOW
|
||||
RETURN
|
||||
|
||||
CENTRY RAND
|
||||
MOVE A,RHI
|
||||
MOVE B,RLOW
|
||||
MOVEM A,RLOW ;Update Low seed
|
||||
LSHC A,-1 ;Shift both right one bit
|
||||
XORB B,RHI ;Generate output and update High seed
|
||||
MOVE A,B
|
||||
RETURN
|
||||
|
||||
.IDATA
|
||||
RHI: 267762113337
|
||||
RLOW: 155256071112
|
||||
.PDATA
|
||||
|
||||
END
|
||||
248
src/clib/stkdmp.c
Normal file
248
src/clib/stkdmp.c
Normal file
@@ -0,0 +1,248 @@
|
||||
# include "c.defs"
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
STKDMP - C Stack Dumping Routine
|
||||
|
||||
This file is PDP-10 dependent, but essentially system
|
||||
independent.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
# rename findproc "FINDPR"
|
||||
# rename findframe "FINDFR"
|
||||
# rename print_name "PRNAME"
|
||||
# rename callok "CALLOK"
|
||||
|
||||
# rename hack "STKDMP"
|
||||
# rename seg2lo "SEG2LO"
|
||||
# rename seg2hi "SEG2HI"
|
||||
# rename seg3lo "SEG3LO"
|
||||
# rename seg3hi "SEG3HI"
|
||||
# rename pdlbot "PDLBOT"
|
||||
# rename pdltop "PDLTOP"
|
||||
# rename purbot "PURBOT"
|
||||
# rename purtop "PURTOP"
|
||||
# rename intptr "INTPTR"
|
||||
# rename mpvh "MPVH"
|
||||
# rename etsint "ETSINT"
|
||||
# rename uuoh "UUOH"
|
||||
# rename uuohan "UUO$HA"
|
||||
# rename euuoh "EUUOH"
|
||||
# rename caller "CALLER"
|
||||
|
||||
# define ADDI_P 0271740
|
||||
# define SUBI_P 0275740
|
||||
# define GO_P 0254037
|
||||
# define JSP_D 0265200
|
||||
# define GO 0254000
|
||||
|
||||
# define left(x) (((x) >> 18) & 0777777)
|
||||
# define right(x) ((x) & 0777777)
|
||||
|
||||
extern int *seg2lo, *seg2hi, *seg3lo, *seg3hi,
|
||||
*pdlbot, *pdltop, *purbot, *purtop, *caller,
|
||||
mpvh[], etsint[], intptr, uuoh[], uuohan[], euuoh[],
|
||||
cout, *findframe(), *findproc(), hack[];
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
STKDMP - Dump stack.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
static int tuuoh;
|
||||
|
||||
stkdmp (fd)
|
||||
|
||||
{int *pc; /* procedure pointer */
|
||||
int *opc; /* previously printed-out pc */
|
||||
int *sp; /* stack pointer */
|
||||
|
||||
if (!cisfd(fd)) fd = cout;
|
||||
cputc ('\n', fd);
|
||||
tuuoh = uuoh[0];
|
||||
sp = &fd; /* arg is on the stack */
|
||||
pc = right(sp[1]); /* my caller's pc is on the stack */
|
||||
opc = -1;
|
||||
--sp; /* top of stack when he was running */
|
||||
if (pc >= hack && pc <= hack+12) /* PUSHJ P,STKDMP$X */
|
||||
{pc = right(sp[0]); /* 'real' caller */
|
||||
sp =- 7; /* 'real' stack top */
|
||||
}
|
||||
while (TRUE)
|
||||
{int *proc, nargs, *npc, *namep, *ap;
|
||||
proc = findproc (pc);
|
||||
if (proc == 0) break;
|
||||
nargs = left(proc[-1]);
|
||||
namep = right(proc[-1]);
|
||||
sp = findframe (sp, proc, pc);
|
||||
if (sp == 0)
|
||||
{if (opc != caller)
|
||||
{cprint (fd, " ");
|
||||
print_name (namep, fd);
|
||||
cprint (fd, "\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
npc = right(sp[0]);
|
||||
sp =- nargs;
|
||||
ap = sp;
|
||||
--sp;
|
||||
cprint (fd, "%7o ", sp);
|
||||
print_name (namep, fd);
|
||||
cprint (fd, " (");
|
||||
if (nargs>10) nargs = 10;
|
||||
while (--nargs >= 0)
|
||||
{cprint (fd, "%o", *ap++);
|
||||
if (nargs) cprint (fd, ", ");
|
||||
}
|
||||
cprint (fd, ")\n");
|
||||
opc = proc;
|
||||
pc = npc;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
FINDPROC - Find beginning of active procedure, given a PC.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int *findproc (pc) int *pc;
|
||||
|
||||
{int *low, *high, n;
|
||||
|
||||
n = 3;
|
||||
while (--n>=0)
|
||||
{if (pc >= mpvh && pc < etsint)
|
||||
{int *p;
|
||||
p = right(intptr);
|
||||
pc = right(p[-4]);
|
||||
continue;
|
||||
}
|
||||
if (pc == uuoh+1 || (pc >= uuohan && pc < euuoh))
|
||||
{pc = right(tuuoh);
|
||||
if ((pc[0]>>29)==0) ++pc; /* hack */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (pc > seg2lo && pc <= seg2hi)
|
||||
{low = seg2lo;
|
||||
high = seg2hi;
|
||||
}
|
||||
else if (pc > purbot && pc <= purtop)
|
||||
{low = purbot;
|
||||
high = purtop;
|
||||
}
|
||||
else return (0);
|
||||
|
||||
++pc;
|
||||
while (--pc > low)
|
||||
{int data, c, nargs, *namep;
|
||||
if ((*pc >> 27) == 0) continue;
|
||||
data = pc[-1];
|
||||
nargs = left(data);
|
||||
namep = right(data);
|
||||
if (nargs >= 16) continue;
|
||||
if (namep < seg3lo || namep > seg3hi) continue;
|
||||
c = (*namep >> 29); /* left byte */
|
||||
if (c < ' ' || c > 'z') continue;
|
||||
return (pc);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
FINDFRAME - Find stack frame, given stack top and procedure
|
||||
pointer, and PC within procedure. Returns pointer
|
||||
to return address on stack.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int *findframe (sp, proc, pc) int *sp, *proc, *pc;
|
||||
|
||||
{int instr, signal();
|
||||
|
||||
instr = proc[0];
|
||||
if (left(instr) == ADDI_P) /* procedure allocates a frame */
|
||||
{int bump;
|
||||
bump = right(instr); /* local frame size */
|
||||
if (pc == proc); /* hasn't allocated it yet */
|
||||
else if (left(pc[0]) == GO_P); /* has popped it */
|
||||
else sp =- bump;
|
||||
}
|
||||
if (pc >= mpvh && pc < etsint) /* was in interrupt handler */
|
||||
sp =- 17; /* ignore stuff pushed by handler */
|
||||
/* !!! the above is wrong !!! */
|
||||
|
||||
++sp;
|
||||
while (--sp >= pdlbot)
|
||||
{int data, *opc;
|
||||
data = *sp;
|
||||
|
||||
/* look for return address word on stack */
|
||||
/* check for reasonable status bits */
|
||||
if (!(data & 0010000000000)) continue;
|
||||
/* must be in user mode */
|
||||
if (data & 0027637000000) continue; /* bad for status bits */
|
||||
|
||||
/* check for reasonable old PC (within code segment) */
|
||||
opc = right(data) - 1;
|
||||
if (opc < seg2lo) continue;
|
||||
if (opc > seg2hi) continue;
|
||||
|
||||
/* check to see if old PC was call to current proc */
|
||||
if (callok (opc, proc))
|
||||
{if (proc == signal && opc>=mpvh && opc<etsint)
|
||||
tuuoh = sp[-1];
|
||||
return (sp);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
CALLOK
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
int callok (opc, proc)
|
||||
int *opc, *proc;
|
||||
|
||||
{int call, *tpc, op;
|
||||
call = *opc;
|
||||
if (call & 037000000) /* index or indirect */
|
||||
return (TRUE); /* can't test it, assume it's the right one */
|
||||
op = left(call); /* op code */
|
||||
tpc = right(call); /* address */
|
||||
if (op == JSP_D) /* call with nargs mismatch */
|
||||
{int n, i; /* look for jump */
|
||||
n = 20; /* up to 20 instructions before jump */
|
||||
for (i=0;i<n;++i)
|
||||
{call = tpc[i];
|
||||
op = left(call);
|
||||
if (op == GO)
|
||||
{tpc = right(call);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (tpc == proc);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PRINTNAME
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
print_name (namep, fd)
|
||||
|
||||
{int c;
|
||||
namep = right(namep) | 0440700000000;
|
||||
while (c = ildb (&namep))
|
||||
cputc (c>='A' && c<='Z' ? c+('a'-'A') : c, fd);
|
||||
}
|
||||
131
src/clib/string.cmid
Normal file
131
src/clib/string.cmid
Normal file
@@ -0,0 +1,131 @@
|
||||
;
|
||||
; STRING - C STRING, BYTE, AND BIT ROUTINES
|
||||
;
|
||||
; This file is PDP-10 dependent, system-independent.
|
||||
;
|
||||
|
||||
TITLE STRING
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
; CONTAINS:
|
||||
|
||||
; SLEN ; STRING LENGTH
|
||||
; STCPY ; STRING COPY
|
||||
; STCMP ; STRING COMPARE
|
||||
; LOWER ; CVT CHAR TO LOWER CASE
|
||||
; UPPER ; CVT CHAR TO UPPER CASE
|
||||
|
||||
; BGET ; BIT ARRAY BIT GET
|
||||
; BSET ; BIT ARRAY BIT SET
|
||||
|
||||
; ILDB ; INCREMENT AND LOAD BYTE
|
||||
; IDPB ; INCREMENT AND DEPOSIT BYTE
|
||||
|
||||
CENTRY SLEN,[STR] ; STRING LENGTH
|
||||
|
||||
MOVE B,STR ; POINTER TO STRING
|
||||
SETZ A, ; COUNTER
|
||||
SL$1: MOVE C,(B) ; GET NEXT CHARACTER
|
||||
SKIPN C
|
||||
GO SL$RET ; RETURN ON NULL CHAR
|
||||
ADDI A,1 ; INCR COUNTER
|
||||
ADDI B,1 ; INCR POINTER
|
||||
GO SL$1
|
||||
SL$RET: RETURN
|
||||
|
||||
CENTRY STCPY,[SRC,DEST] ; STRING COPY
|
||||
|
||||
; COPY STRING FROM SRC TO DEST
|
||||
; RETURN POINTER TO NULL TERMINATING NEW COPY
|
||||
|
||||
MOVE B,SRC ; SOURCE POINTER
|
||||
MOVE A,DEST ; DESTINATION POINTER
|
||||
SC$1: MOVE C,(B) ; GET NEXT CHAR
|
||||
MOVEM C,(A) ; STORE
|
||||
SKIPN C
|
||||
GO SC$RET ; RETURN AFTER WRITING NULL CHAR
|
||||
ADDI B,1 ; INCR SOURCE PTR
|
||||
ADDI A,1 ; INCR DESTINATION PTR
|
||||
GO SC$1
|
||||
SC$RET: RETURN
|
||||
|
||||
CENTRY STCMP,[S1,S2] ; STRING COMPARE
|
||||
|
||||
MOVE B,S1
|
||||
MOVE C,S2
|
||||
SM$1: MOVE A,(B) ; GET NEXT CHAR
|
||||
CAME A,(C)
|
||||
GO SM$2 ; DIFFERENCE FOUND
|
||||
ADDI B,1 ; INCR PTR1
|
||||
ADDI C,1 ; INCR PTR2
|
||||
JUMPN A,SM$1
|
||||
SETO A,
|
||||
GO SM$RET
|
||||
SM$2: SETZ A,
|
||||
SM$RET: RETURN
|
||||
|
||||
CENTRY LOWER,[CH] ; CVT CHAR TO LOWER CASE
|
||||
|
||||
MOVE A,CH
|
||||
CAIGE A,"A
|
||||
GO LW$RET
|
||||
CAILE A,"Z
|
||||
GO LW$RET
|
||||
ADDI A,"a-"A
|
||||
LW$RET: RETURN
|
||||
|
||||
CENTRY UPPER,[CH] ; CVT CHAR TO UPPER CASE
|
||||
|
||||
MOVE A,CH
|
||||
CAIGE A,"a
|
||||
GO UP$RET
|
||||
CAILE A,"z
|
||||
GO UP$RET
|
||||
SUBI A,"a-"A
|
||||
UP$RET: RETURN
|
||||
|
||||
CENTRY BGET,[BARRAY,BINDEX] ; BIT ARRAY BIT GET
|
||||
|
||||
HRRZ C,BINDEX
|
||||
HRRZ A,BARRAY
|
||||
MOVEI B,(C) ; SUBSCRIPT
|
||||
|
||||
LSH C,-5 ; GET WORD OFFSET
|
||||
ADDI A,(C) ; GET WORD ADDRESS
|
||||
MOVE A,(A) ; GET THE WORD
|
||||
ANDI B,37 ; BIT OFFSET
|
||||
ROT A,1(B) ; PUT BIT IN RIGHT-MOST POSITION
|
||||
ANDI A,1 ; GET THE BIT
|
||||
RETURN
|
||||
|
||||
CENTRY BSET,[BARRAY,BINDEX] ; BIT ARRAY BIT SET
|
||||
|
||||
HRRZ C,BINDEX
|
||||
HRRZ A,BARRAY
|
||||
MOVEI B,(C) ; SUBSCRIPT
|
||||
|
||||
LSH C,-5 ; GET WORD OFFSET
|
||||
ADDI A,(C) ; GET WORD ADDRESS
|
||||
ANDI B,37 ; BIT OFFSET
|
||||
MOVN B,B ; NEGATIVE BIT OFFSET
|
||||
MOVEI C,1 ; A BIT
|
||||
ROT C,-1(B) ; PUT IN RIGHT POSITION
|
||||
IORM C,(A) ; SMASH ARRAY WORD
|
||||
MOVEI A,1
|
||||
RETURN
|
||||
|
||||
CENTRY ILDB,[ABPTR] ; INCREMENT AND LOAD BYTE
|
||||
|
||||
HRRZ A,ABPTR ; ADDRESS OF BYTE POINTER
|
||||
ILDB A,(A)
|
||||
RETURN
|
||||
|
||||
CENTRY IDPB,[CH,ABPTR] ; INCREMENT AND DEPOSIT BYTE
|
||||
|
||||
MOVE B,CH ; THE CHARACTER
|
||||
HRRZ A,ABPTR ; ADDRESS OF BYTE POINTER
|
||||
IDPB B,(A)
|
||||
RETURN
|
||||
|
||||
END
|
||||
18
src/clib/tstfd.c
Normal file
18
src/clib/tstfd.c
Normal file
@@ -0,0 +1,18 @@
|
||||
/**********************************************************************
|
||||
|
||||
TSTFD
|
||||
Test routine for FD
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
main ()
|
||||
|
||||
{char buf[200];
|
||||
extern int puts ();
|
||||
for (;;)
|
||||
{cprint ("Enter pattern: ");
|
||||
gets (buf);
|
||||
fdmap (buf, puts);
|
||||
puts ("");
|
||||
}
|
||||
}
|
||||
123
src/clib/ttime.c
Normal file
123
src/clib/ttime.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/**********************************************************************
|
||||
|
||||
TTIME - Test program for Timing
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
# rename timing "TIMING"
|
||||
extern int timing;
|
||||
|
||||
main ()
|
||||
|
||||
{int i;
|
||||
i = 10000;
|
||||
if (timing) i = 1000;
|
||||
while (--i >= 0) foo ();
|
||||
}
|
||||
|
||||
foo () /* calls null 100 times */
|
||||
|
||||
{
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
null();
|
||||
}
|
||||
|
||||
null () {;}
|
||||
156
src/clib/uuoh.cmid
Normal file
156
src/clib/uuoh.cmid
Normal file
@@ -0,0 +1,156 @@
|
||||
;
|
||||
; UUOH - C UUO Handler
|
||||
;
|
||||
; This file is PDP-10 dependent, system-independent.
|
||||
;
|
||||
|
||||
TITLE UUOH
|
||||
.INSRT NC
|
||||
.INSRT NM
|
||||
|
||||
;
|
||||
; UUO DISPATCH TABLE
|
||||
;
|
||||
|
||||
.PDATA
|
||||
IENTRY UUOTAB
|
||||
ILLUUO
|
||||
UCCALL ;.CCALL - FIRST TIME CALL
|
||||
UVCALL ;.VCALL - CALL OF VARIABLE PROC
|
||||
UACALL ;.ACALL - CALL NEEDING ADDITIONAL ARGS
|
||||
UXCALL ;.XCALL - CALL WITH EXTRA ARGS
|
||||
REPEAT UUOTAB+40-.,[ILLUUO?]
|
||||
|
||||
;
|
||||
; BASIC UUO DISPATCHER
|
||||
;
|
||||
|
||||
.IDATA
|
||||
MDATA UUOH
|
||||
0
|
||||
GO UUO$HANDLER
|
||||
MDATA SMASH
|
||||
-1
|
||||
.UDATA
|
||||
MDATA USAVEA
|
||||
BLOCK 1
|
||||
MDATA USAVEB
|
||||
BLOCK 2
|
||||
MDATA USAVEC
|
||||
BLOCK 3
|
||||
MDATA USAVED
|
||||
BLOCK 4
|
||||
.CODE
|
||||
|
||||
IENTRY UUO$HANDLER
|
||||
|
||||
MOVEM D,USAVED
|
||||
LDB D,[330500,,40] ; GET UUO CODE
|
||||
GO @UUOTAB(D) ; DISPATCH BASED ON THE UUO
|
||||
|
||||
URETA: MOVE A,USAVEA
|
||||
URETB: MOVE B,USAVEB
|
||||
URETC: MOVE C,USAVEC
|
||||
URETD: MOVE D,USAVED
|
||||
GO @UUOH
|
||||
|
||||
;
|
||||
; ILLEGAL UUO HANDLER
|
||||
;
|
||||
|
||||
IENTRY ILLUUO
|
||||
|
||||
CROAK ILLEGAL UUO
|
||||
GO URETD
|
||||
|
||||
;
|
||||
; .CCALL HANDLER
|
||||
;
|
||||
|
||||
IENTRY UCCALL
|
||||
|
||||
MOVEM B,USAVEB ; MUST NOT CHANGE ANY REGS
|
||||
MOVEM C,USAVEC ; AS CALL MIGHT BE THRU A REG
|
||||
HRRZ C,40 ; THE CALLED PROCEDURE
|
||||
JUMPE C,UCBAD ; NO SUCH PROCEDURE
|
||||
HLRZ 0,-1(C) ; THE NUMBER OF FORMAL ARGS
|
||||
CAIL 0,20 ; REASONABLE NUMBER?
|
||||
GO UCBAD ; NO, NOT A PROCEDURE
|
||||
SKIPN SMASH ; SHOULD I SMASH THE CALL
|
||||
GO UC$GO ; NO, LEAVE IT
|
||||
SOS D,UUOH ; ADDRESS OF THE CALL
|
||||
MOVE B,(D) ; THE .CCALL INSTRUCTION
|
||||
TLZ B,777740 ; ZERO OUT ALL BUT ADDRESS PART
|
||||
CAIE B,(C) ; IS IT A CONSTANT CALL?
|
||||
GO UCV ; NO, CHANGE IT INTO A .VCALL
|
||||
LDB B,[270400,,40] ; THE NUMBER OF ACTUAL ARGS
|
||||
HLRZ 0,-1(C) ; THE NUMBER OF FORMAL ARGS
|
||||
SUB B,0 ; THE NUMBER OF EXTRA ACTUALS
|
||||
JUMPL B,UCA ; TOO FEW ACTUALS
|
||||
JUMPG B,UCX ; TOO MANY ACTUALS
|
||||
MOVEI B,(PUSHJ P,)
|
||||
HRLM B,(D) ; SMASH .CCALL TO PUSHJ
|
||||
GO URETB ; RE-EXECUTE CALL
|
||||
|
||||
UCA: MOVN B,B ; THE NUMBER OF EXTRA ARGS NEEDED
|
||||
LSH B,5 ; SHIFT INTO ACCUMULATOR POSITION
|
||||
IORI B,(.ACALL)
|
||||
HRLM B,(D) ; SMASH .CCALL TO .ACALL
|
||||
GO URETB ; RE-EXECUTE CALL
|
||||
UCX: LSH B,5 ; SHIFT INTO ACCUMULATOR POSITION
|
||||
IORI B,(.XCALL)
|
||||
HRLM B,(D) ; SMASH .CCALL TO .ACALL
|
||||
GO URETB ; RE-EXECUTE CALL
|
||||
UCV: MOVE B,(D) ; THE ORIGINAL CALL
|
||||
TLZ B,777000 ; MASK OUT OPCODE
|
||||
TLO B,(.VCALL) ; MAKE IT A .VCALL
|
||||
MOVEM B,(D) ; SMASH CALL
|
||||
GO URETB ; RE-EXECUTE CALL
|
||||
|
||||
IENTRY UCBAD
|
||||
LDB B,[270400,,0] ; THE NUMBER OF ACTUAL ARGS
|
||||
UVBAD: MOVEM B,USAVEA ; SAVE NUMBER OF ACTUAL ARGS
|
||||
SETZ A, ; SET DEFAULT RETURN VALUE
|
||||
MOVE D,UUOH
|
||||
SUBI D,1 ; LET USER LOOK AT CALL
|
||||
CROAK CALL OF UNDEFINED PROCEDURE
|
||||
SUB P,USAVEA ; POP OFF ARGS
|
||||
GO URETB ; RETURN TO CALLER
|
||||
|
||||
IENTRY UVCALL
|
||||
|
||||
HRRZ C,40 ; THE CALLED PROCEDURE
|
||||
JUMPE C,UVBAD ; NO SUCH PROCEDURE
|
||||
HLRZ 0,-1(C) ; THE NUMBER OF FORMAL ARGS
|
||||
CAIL 0,20 ; REASONABLE NUMBER?
|
||||
GO UVBAD ; NO, NOT A PROCEDURE
|
||||
UC$GO: LDB B,[270400,,40] ; THE NUMBER OF ACTUAL ARGS
|
||||
SUB 0,B ; NUMBER OF ARGS NOT GIVEN
|
||||
JUMPL 0,UVHACK ; TOO MANY ARGS GIVEN
|
||||
UVLOOP: SOJL 0,UVDOIT ; FOR EACH ARG NEEDED
|
||||
PUSH P,[0] ; PUSH ZERO ARG
|
||||
GO UVLOOP ; LOOP
|
||||
|
||||
UVHACK: ; TOO MANY ARGS GIVEN
|
||||
ADD P,0 ; POP OFF EXTRA ARGS
|
||||
UVDOIT: PUSH P,UUOH ; PUSH RETURN ADDRESS
|
||||
GO (C) ; EXECUTE PROCEDURE
|
||||
|
||||
IENTRY UACALL
|
||||
|
||||
LDB B,[270400,,40] ; THE NUMBER OF EXTRA ARGS NEEDED
|
||||
HRRZ C,40 ; THE CALLED PROCEDURE
|
||||
UALOOP: SOJL B,UVDOIT ; FOR EACH ARG NEEDED
|
||||
PUSH P,[0] ; PUSH ZERO ARG
|
||||
GO UALOOP ; LOOP
|
||||
|
||||
IENTRY UXCALL
|
||||
|
||||
LDB B,[270400,,40] ; THE NUMBER OF EXTRA ARGS
|
||||
HRRZ C,40 ; THE CALLED PROCEDURE
|
||||
SUBI P,(B) ; POP OFF EXTRA ARGS
|
||||
PUSH P,UUOH ; PUSH RETURN ADDRESS
|
||||
GO (C) ; EXECUTE PROCEDURE
|
||||
|
||||
IENTRY EUUOH
|
||||
END
|
||||
Reference in New Issue
Block a user