TITLE LOSS DEVICE

A=1	;TEMP	;USUALLY BOJ OPCODE WORD
B=2	;TEMP	;FILE NAME 1 DURING OPEN
C=3	;TEMP	;FILE NAME 2 DURING OPEN
D=4	;TEMP
E=5	;ERRORS (ERROR # IN LH, SKIP COUNT IN RIGHT)
F=6	;FLAGS
M=7	;I/O MODE AS SEEN BY LOSER
N=10	;SEMI-TEMPORARY
Q=11	;BYTE POINTER OR BLOCK POINTER FOR SENDING TO LOSER
S=12	;CHANNEL STATUS SPECIFIED BY LOSER
W=13	;# OF WDS OR CHARS BEFORE GIVING EOF/DEVFULL
U=16	;FOR INTERRUPT LEVEL ONLY
P=17	;PDL

BOJC=15	;BOJ CHANNEL

LPDL==10	;LENGTH OF PDL

;;; FLAGS IN LEFT HALF OF F

%FOPEN==400000	;OPEN HAS SUCCEEDED
%FDIR==200000	;DIRECTORY MODE
%FIOC==100000	;IOC ERROR MODE
%FINT==40000	;INTERRUPT ON LOSER'S .IOT
%FINTR==20000	;INTERRUPT RANDOMLY

LOC 41
	JSR UUOH
	JSR TSINT

LOC 100
UUOH:	0		;UUO HANDLER
	JRST DIE	;DON'T USE ANY!

TSINT:	0		;INTERRUPT WORD
	0		;RETURN ADDRESS
	SKIPL U,TSINT
	 JRST TSINT1	;WORD 1 INTERRUPT
	TRNN U,1_BOJC	;WORD 2 - BETTER BE BOJC
	 JRST DIE
	SETOM INT	;SIGNAL RECEIPT OF INTERRUPT
	.DISMISS TSINT+1

TSINT1:	TLNE U,200000	;BETTER BE REAL TIME INTERRUPT
	 TLNN F,%FINTR	; AND RANDOM INT FLAG BETTER BE SET
	  JRST DIE
	JUMPL S,TSINT2	;JUMP UNLESS JOB STATUS SET UP
	.CALL JOBSTS
	 JRST DIE
TSINT2:	.CALL JOBINT	;SO GIVE LOSER A RANDOM INTERRUPT
	 JRST DIE
	.DISMISS TSINT+1

INT:	0		;NEG => INTERRUPT RECEIVED ON BOJC

JOBSTS:	SETZ
	SIXBIT \JOBSTS\		;SET JOB CHANNEL STATUS
	  1000,,BOJC		;BOJ CHANNEL #
	400000,,S		;NEW CHANNEL STATUS

JOBINT:	SETZ
	SIXBIT \JOBINT\		;GIVE INTERRUPT ON JOB CHANNEL
	401000,,BOJC		;BOJ CHANNEL #

JOBCON:	SETZ
	SIXBIT \JOBRET\		;RETURN TO LOSER
	  1000,,BOJC		;BOJ CHANNEL #
	400000,,E		;<ERROR #>,,<SKIP AMOUNT>

OPNLUZ:	.CALL JOBCON		;WANT TO ERROR OUT ON .OPEN
	 JFCL			; - ERROR # IN LH OF E
DIE:	.LOGOUT			;COMMIT SUICIDE
	.VALUE [ASCIZ \.JPC/\]	;IF CAN'T, MUST BE DEBUGGING

PDL:	BLOCK LPDL		;NOT USED MUCH ANYWAY

GO:	MOVE P,[-LPDL,,PDL-1]
	SETZB F,INT
	SETO S,
	.OPEN BOJC,[17,,'BOJ]
	 JRST DIE
	.SUSET [.SMASK,,[200000,,]]	;REAL TIME CLOCK
	.SUSET [.SMSK2,,[1_BOJC]]	;BOJ CHANNEL
	.SUSET [.SIFPIR,,[1_BOJC]]	;FAKE INT TO GET GOING
LOOP:	JUMPL S,LOOP1
	.CALL JOBSTS
	 JRST DIE
LOOP1:	SKIPL INT		;WAIT FOR BOJ INTERRUPT
	 .HANG
	SETZM INT
	MOVE D,[-12,,JOBBLK]
	.CALL JOBCAL		;GET CRUFT ABOUT BOJ REQUEST
	 JRST JBCLUZ
	TLNE A,60000
	 JRST CLOSE		;WANT TO CLOSE UP SHOP
	JRST @.+1(A)		;RH OF A HAS I/O OPCODE
	 OPEN
	 IOT
	 STATUS
	 RESET
	 RCHST
	 ACCESS
	 FDELE
	 RENMWO
	 CALL

JBCLUZ:	TLNN F,%FOPEN		;JOBCAL LOST
	 JRST DIE
	JRST LOOP

JOBCAL:	SETZ
	SIXBIT \JOBCAL\		;GET INFO ABOUT JOB CALL
	  1000,,BOJC		;BOJ CHANNEL #
	  2000,,A		;BOJ REQUEST OPCODE
	400000,,D		;BLOCK POINTER TO DATA AREA

JOBBLK:	BLOCK 12		;ROOM FOR BOJ REQUEST DATA

OPENUP:	SETZ
	SIXBIT \OPEN\		;OPEN FILE
	  4000,,MODETB(M)	;MODE
	  1000,,BOJC		;CHANNEL #
	      ,,[SIXBIT \BOJ\]	;DEVICE NAME
	400000,,0	;CRETINOUS ITS CURRENTLY DEMANDS THIS

MODETB:	31	;BASICALLY,
	30	; WANT
	33	; TO OPEN
	32	; IN
	35	; MODE
	34	; INVERSE
	37	; TO
	36	; LOSER'S

OPEN:	TLNE F,%FOPEN		;MUSTN'T ALREADY BE OPEN
	 JRST DIE
	LDB M,[410300,,A]	;I/O MODE
	.CALL OPENUP		;RE-OPEN BOJ IN CORRECT MODE
	 JRST DIE
	MOVE B,JOBBLK+1		;FILE NAME 1
	MOVE C,JOBBLK+2		;FILE NAME 2
	CAMN B,[SIXBIT \.FILE.\]
	 CAME C,[SIXBIT \(DIR)\]
	  JRST OPEN1
	MOVSI E,12		;"MODE NOT AVAILABLE"
	TRNE M,5		;CAN ONLY GIVE ASCII DIRECTORY
	 JRST OPNLUZ
	MOVE Q,[-LDIR,,DIR]
	MOVEI W,LCHDIR
	.OPEN BOJC,[33,,'BOJ]	;RE-OPEN BOJ IN ASCII BLOCK OUTPUT
	 JRST DIE
	MOVEI M,2		;ASSUME LOSER IS BLOCK MODE TOO
	TLO F,%FDIR		;WE'RE IN DIRECTORY MODE
OPNOK:	TLO F,%FOPEN
	MOVEI E,1		;SINGLE SKIP
	MOVEM B,CHSTAT+1	;SAVE FILE NAMES FOR .RCHST
	MOVEM C,CHSTAT+2
CONTIN:	.CALL JOBCON		;CONTINUE THE LOSER
	 JRST DIE
	JRST LOOP		;CONTINUE US

OPEN1:	CAME B,[SIXBIT \IOC\]
	 JRST OPEN1A
	PUSHJ P,GETN		;IOC ERROR MODE
	JUMPLE N,BADNAM		;CHECK SECOND FILE NAME
	CAILE N,LIOCTB/2
	 JRST OPEN1B		;CODE TOO HIGH, PUNT THE FILE NAME BUT WORK ANYWAY
	MOVEI D,(N)		;TRANSLATE NAMES FOR .RCHST
	LSH D,1
	MOVE B,IOCTB-2(D)
	MOVE C,IOCTB-1(D)
	JRST OPEN1B

OPEN1A:	MOVE D,[-LIOCTB,,IOCTB]
	PUSHJ P,LOOKUP
	 JRST OPEN2
OPEN1B:	TLO F,%FIOC
	JRST OPNOK

OPEN2:	HLLZ D,B
	CAME D,[SIXBIT \INT\]
	 JRST OPEN4
	PUSHJ P,GETN		;INTERRUPT MODE
	MOVE S,N		;LOSER-SPECIFIED STATUS
	TLO F,%FINT
	HRLZ D,B
	JUMPE D,OPNOK		;INT ON .IOT
	PUSHJ P,GETN
	TLC F,%FINT+%FINTR	;INT AFTER SPECIFIED TIME
	SKIPN D,N
	 MOVEI D,1
	IMULI D,30.
	MOVE N,[600000,,D]
	.REALT N,
INFINI:	MOVSI W,200000		;INFINITY (377777,, LOSES - SEE 2IOT)
IOTOK:	MOVE Q,IOTPTR(M)
	JRST OPNOK

IOTPTR:	440700,,TRIX		;ASCII UNIT INPUT (FOR LOSER)
	0			;ASCII UNIT OUTPUT (UNUSED)
	-LTRIX,,TRIX		;ASCII BLOCK INPUT
	-LFLUSH,,FLUSH		;ASCII BLOCK OUTPUT
	31416,,0		;IMAGE UNIT INPUT
	0			;IMAGE UNIT OUTPUT (UNUSED)
	31416,,0		;IMAGE BLOCK INPUT
	-LFLUSH,,FLUSH		;IMAGE BLOCK OUTPUT

OPEN4:	CAME B,[SIXBIT \STATUS\]
	 JRST OPEN5
	PUSHJ P,GETN		;USER-SPECIFIED STATUS
	MOVEI S,(N)
	JRST INFINI

OPEN5:	CAME B,[SIXBIT \EOF\]
	 JRST ERRS
	PUSHJ P,GETN		;EOF/DEVICE FULL DEVICE
	MOVE W,N
	JRST IOTOK

FDELE:	MOVE B,JOBBLK+1		;FILE FILE NAME
	MOVE C,JOBBLK+2		;SECOND FILE NAME
ERRS:	CAME B,[SIXBIT \ERR\]
	 CAMN B,[SIXBIT \ERROR\]
	  JRST ERROR
	MOVE D,[-LERRTB,,ERRTB]
	PUSHJ P,LOOKUP
BADNAM:	 MOVEI N,11		;"ILLEGAL FILE NAME"
FATALN:	MOVSI E,(N)
FATAL:	.CALL JOBCON
	 JRST DIE
	JRST DIE

ERROR:	PUSHJ P,GETN
	JUMPLE N,BADNAM
	CAILE N,LERRTB/2
	 JRST FATALN		;IF OUT OF RANGE, PUNT ON THE NAME, BUT WORK ANYWAY
	JRST FATALN

;;; LOOK UP A PAIR OF FILE NAMES IN B AND C IN A TABLE WHOSE
;;; AOBJN POINTER IS IN D. SKIPS ON SUCCESS, LEAVING INDEX IN N.

LOOKUP:	MOVEI N,-2(D)
LOOK0:	CAMN B,(D)
	 CAME C,1(D)
	  JRST LOOK1
	SUBI N,(D)
	MOVNS N
	LSH N,-1
POPJ1:	AOS (P)
	POPJ P,

LOOK1:	AOBJP D,DIE
	AOBJN D,LOOK0
	POPJ P,

;;; STANDARD TABLE OF .CALL-TYPE ERROR FILE NAMES

ERRTB:	SIXBIT \NOSUCHDEVICE\	; 1	NO SUCH DEVICE
	SIXBIT \WRONG DIREC \	; 2	WRONG DIRECTION
	SIXBIT \2MANY TRANSL\	; 3	TOO MANY TRANSLATIONS
	SIXBIT \FILNOTFOUND \	; 4	FILE NOT FOUND
	SIXBIT \DIR   FULL  \	; 5	DIRECTORY FULL
	SIXBIT \DEVICEFULL  \	; 6	DEVICE FULL
	SIXBIT \DEVNOTREADY \	; 7	DEVICE NOT READY
	SIXBIT \DEVNOTAVAIL \	;10	DEVICE NOT AVAILABLE
	SIXBIT \ILGL  FILNAM\	;11	ILLEGAL FILE NAME
	SIXBIT \MODNOTAVAIL \	;12	MODE NOT AVAILABLE
	SIXBIT \FILE  EXISTS\	;13	FILE ALREADY EXISTS
	SIXBIT \BAD   CHAN# \	;14	BAD CHANNEL NUMBER
	SIXBIT \2MANY ARGS  \	;15	TOO MANY ARGUMENTS (CALL)
	SIXBIT \PAKNOTMOUNT \	;16	PACK NOT MOUNTED
	SIXBIT \DIRNOTAVAIL \	;17	DIRECTORY NOT AVAIL
	SIXBIT \NON-EXUSRNAM\	;20	NON-EXISTENT USER NAME
	SIXBIT \LOCAL DEVICE\	;21	LOCAL DEVICE ONLY
	SIXBIT \SELF  CONTRA\	;22	SELF-CONTRADICTORY OPEN
	SIXBIT \FILE  LOCKED\	;23	FILE LOCKED
	SIXBIT \M.F.D.FULL  \	;24	M.F.D. FULL
	SIXBIT \DEVNOTASSIGN\	;25	DEVICE NOT ASSIGNABLE TO THIS PROCESSOR
	SIXBIT \WRITE LOCKED\	;26	DEVICE WRITE-LOCKED
	SIXBIT \LINK  DEPTH \	;27	LINK DEPTH EXCEEDED
	SIXBIT \2FEW  ARGS  \	;30	TOO FEW ARGUMENTS (CALL)
	SIXBIT \CAN'T MODIFY\	;31	CAN'T MODIFY JOB
	SIXBIT \CAN'T ACCESS\	;32	CAN'T GET THAT ACCESS TO PAGE
	SIXBIT \LOSINGARGS  \	;33	MEANINGLESS ARGS
	SIXBIT \WRONG TYPE  \	;34	WRONG TYPE DEVICE
	SIXBIT \NOSUCHJOB   \	;35	NO SUCH JOB
	SIXBIT \VALCLRSTOSET\	;36	VALID CLEAR OR STORED SET
	SIXBIT \NOCOREAVAIL \	;37	NO CORE AVAILABLE
	SIXBIT \NOTTOPLEVEL \	;40	NOT TOP LEVEL
	SIXBIT \OTHER END   \	;41	OTHER END OF PIPELINE GONE OR NOT OPEN
	SIXBIT \JOB   GONE  \	;42	JOB GONE OR GOING AWAY
	SIXBIT \ILLEGLCALL  \	;43	ILLEGAL SYSTEM CALL NAME
	SIXBIT \CHNLNTOPEN  \	;44	CHANNEL NOT OPEN
	SIXBIT \IEMPTYOFULL \	;45	INPUT BUF. EMPTY OR OUT. BUF. FULL
	SIXBIT \UNREC FILE  \	;46	UNRECOGNIZABLE FILE
	SIXBIT \LINKTONONEXF\	;47	LINK TO NON-EXISTENT FILE
LERRTB==.-ERRTB

IOCTB:	SIXBIT \HARDWROP    \	; 1	ILLEGAL HARDWARE OPERATION ATTEMPTED
	SIXBIT \ACCESS>EOF  \	; 2	ATTEMPTED RANDOM ACCESS TO ADDRESS BEYOND END OF FILE
	SIXBIT \DATA  ERROR \	; 3	NON-RECOVERABLE DATA ERROR
	SIXBIT \NON-EXSUBDEV\	; 4	NON-EXISTENT SUB-DEVICE
	SIXBIT \OVER  IOPOP \	; 5	OVER IOPOP
	SIXBIT \OVER  IOPUSH\	; 6	OVER IOPUSH
	SIXBIT \USRCHNNOTUSR\	; 7	USR OP CHNL DOES NOT HAVE USR OPEN
	SIXBIT \CHANOTOPEN  \	;10	CHNL NOT OPEN
	SIXBIT \DEV   FULL  \	;11	DEVICE FULL
	SIXBIT \ILGL  MODE  \	;12	CHNL IN ILLEGAL MODE ON IOT
	SIXBIT \ILGL  ^PCODE\	;13	ILLEGAL CHR AFTER CNTRL P ON TTY DISPLAY
LIOCTB==.-IOCTB

RESET:	JRST IGNORE		;GOOD PLACES FOR BREAKPOINTS
STATUS:	JRST IGNORE
ACCESS:	JRST IGNORE
RENMWO:	JRST IGNORE
CALL:	JRST IGNORE

IGNORE:	MOVEI E,1		;IGNORE RANDOM COMMAND
	.CALL JOBCON
	 JRST DIE
	JRST LOOP

CLOSE:	JRST DIE		;SO DIE, ALREADY

RCHST:	TLNN F,%FOPEN
	 JRST DIE
	MOVEI E,1
	MOVE D,[-6,,CHSTAT]
	.CALL JOBRET
	 JRST DIE
	JRST LOOP

JOBRET:	SETZ
	SIXBIT \JOBRET\		;RETURN STUFF TO LOSER
	  1000,,BOJC		;BOJ CHANNEL #
	      ,,E		;RETURN SPEC
	400000,,D		;AOBJN POINTER TO DATA

CHSTAT:	'LOS			;CRETINOUS .RCHST!
	0			;FILE NAME 1	;FILLED IN
	0			;FILE NAME 2	; BY OPEN
	0			;NULL SNAME
	-1			;NOT RANDOM ACCESS
	0			;???

TRIX:	ASCII \SILLY RABBIT, TRIX ARE FOR KIDS!!î\	
	;MULTIPLE OF 5 CHARS
LTRIX==.-TRIX
	0	;NEED A ZERO WORD - SEE 0IOT

;;; GIVEN FILE NAME IN C, RETURN NUMBER IN N.
;;; FILE NAME MAY BE 0,,NNNNNN OR MAY BE SIXBIT \NNNNNN\.
;;; CLOBBERS D.

GETN:	MOVEI N,(C)
	TLNN C,-1
	 POPJ P,
	PUSH P,C		;MUST PRESERVE C
GETN1:	SETZ D,
	ROTC C,6
	SUBI D,20
	JUMPL D,BADNAM
	CAIL D,8.
	  JRST BADNAM
	;;TRC D,20
	;;TRNE D,70
	 ;;JRST BADNAM
	LSH N,3
	ADDI N,(D)
	JUMPN C,GETN1
	POP P,C
	POPJ P,

IOT:	TLNN F,%FOPEN		;MUST BE OPEN TO IOT!
	 JRST DIE
	TLNN F,%FIOC		;SKIP IF WE WANT AN IOC ERROR
	 JRST IOT1
IOTIOC:	.CALL SETIOC
	 JRST DIE
	JRST LOOP

SETIOC:	SETZ
	SIXBIT \SETIOC\		;SET IOC ERROR
	  1000,,BOJC		;BOJ CHANNEL #
	400000,,N		;IOC ERROR NUMBER

IOT1:	TLNN F,%FINT		;SKIP IF WE WANT RANDOM INTERRUPT
	 JRST IOT2
	.CALL JOBINT
	 JRST DIE
	JRST LOOP

IOT2:	JUMPG W,@IOTJ(M)	;JUMP ON MODE UNLESS EOF
	MOVEI E,1
	TRNN M,1
	 JRST CONTIN		;FOR INPUT, JUST DON'T SEND ANYTHING
	MOVEI N,11		;"DEVICE FULL" (IOC ERROR)
	JRST IOTIOC

IOTJ:	0IOT	;ASCII UNIT INPUT
	1IOT	;ASCII UNIT OUTPUT
	2IOT	;ASCII BLOCK INPUT
	3IOT	;ASCII BLOCK OUTPUT
	4IOT	;IMAGE UNIT INPUT
	5IOT	;IMAGE UNIT OUTPUT
	6IOT	;IMAGE BLOCK INPUT
	7IOT	;IMAGE BLOCK OUTPUT

0IOT0:	MOVE Q,IOTPTR+0
0IOT:	ILDB A,Q		;GOBBLE CHAR FOR LOSER
	JUMPE A,0IOT0		;RAN OUT - CIRCLE BACK
1IOT:	.IOT BOJC,A		;SEND LOSER THE CHAR (OR GOBBLE ONE)
	SOJA W,LOOP		;DECR CHAR COUNT

2IOT:	HLRE A,Q		;GET COUNT OF WORDS LEFT IN IOT PTR
	MOVNS A
	MOVE B,W
	ADDI B,4
	IDIVI B,5
	CAMLE B,A
	 JRST 2IOT3
	MOVN A,B
	HRLM A,Q
	MOVE D,MASKS(C)
	ADDI B,-1(Q)
	MOVE C,[014060301406]	;FIVE ^C'S
	ANDM D,C
	ANDCAM D,(B)
	IORM C,(B)
2IOT3:	ADDI W,(Q)
	.IOT BOJC,Q
	SUBI W,(Q)
	SKIPL Q			;MIGHT NOT HAVE RUN OUT
	 MOVE Q,IOTPTR+2
	JRST LOOP

MASKS:	3760			;RANDOM MASKS FOR INSTALLING ^C'S
	77760
	177,,77760
	3777,,777760
	0

;;; *** TEMP ***
DIR==TRIX
LDIR==LTRIX
LCHDIR==5*LDIR
LFLUSH==50
FLUSH:	BLOCK LFLUSH

;I GUESS TGQ DIDN'T FEEL LIKE BOTHERING TO WRITE THESE
3IOT:
4IOT:
5IOT:
6IOT:
7IOT:	JRST IOTIOC	;FOR WANT OF ANYTHING BETTER TO DO

END GO
