Google
 

Trailing-Edge - PDP-10 Archives - bb-x130a-sb - niklib.mac
There is 1 other file named niklib.mac in the archive. Click here to see a list.
	UNIVER	TSKUNV	SYMBOLS FOR TSKSPL ROUTINES

	SALL			;PRETTY LISTINGS

	SEARCH	UUOSYM,MACTEN

	%%NIKP==:3		;[14] OUR MAJOR (PROTOCOL) LEVEL

SUBTTL	REGISTER DEFINITIONS AND USES

	OPDEF	ERROR[001000,,000000]

	DEFINE	BITCH(TEXT),<
	PUSHJ	P,BITCHM	;;BITCH ABOUT TSKSER I/O BUG
	JFCL	[ASCIZ\TEXT
\]				;;THE TEXT TO USE
> ;END OF BITCH MACRO

R0=0		;SCRATCH	TEMP
R1=1		;TEMP
R2=2		;TEMP
R3=3		;TEMP
R4=4		;TEMP
R5=5		;TEMP
PTR=6		;BYTE POINTER
CHR=7		;CHARACTER---TEMP
P1=10		;TOP LEVEL ONLY
P2=11		;TOP LEVEL ONLY
J=15		;FOR LOW-LEVEL I/O ROUTINES TO JSP AROUND
B=16		;POINTER TO BASE OF DATA SEGMENT
P=17		;STACK POINTER
;	CHANNEL ASSIGNMENTS

$TSK==1
$DSK==2
$LOG==3


;NETWORK I/O MODE SPECIFICATION
;USE ASCII MODE (.IOASC) TO GUARANTEE INDEPENDENCE OF THE USUAL
;TSKSER I/O BUGS BY PACKING -10 WORDS AS 6-BIT BYTES (+100).
;
;USE IMAGE MODE (.IOIMG) IF YOU TRUST THE NETWORK (LESS CPU-
;INTENSIVE).

ND	NTIOM,.IOIMG	;SEE IF NETSER IS BEHAVING ITSELF.

IFE	NTIOM-.IOASC,<
	NIKNM1=='NIK   '
	NIKNM2=='ANYNIK'
>
IFE	NTIOM-.IOIMG,<
	NIKNM1=='NIM   '
	NIKNM2=='ANYNIM'
>


;	COMPLETION AND IDENTIFICATION CODES

TK.CFL==301	;REMOTE CLOSE FAILED
TK.CCF==302	;REMOTE CLOSE CHECKSUM FAILURE
TK.COK==303	;REMOTE CLOSED AND COMPLETED

TK.EFL==310	;REMOTE ENTER FAILED
TK.EOK==311	;REMOTE ENTER SUCCEEDED

TK.INI==320	;THIS BLOCK IS START OF A NEW FILE SPEC
SUBTTL	SYMBOL DEFINITIONS FOR THE DATA BLOCK

DEFINE	X(SYM,ALC),
<IFB <ALC>,<SYM==<..OFS==..OFS+1>-1> IFNB <ALC>,<SYM==<..OFS==..OFS+<ALC>>-<ALC>>>

.XCREF
..OFS==0
.XCREF	..OFS
.CREF

	.RBMAX==.RBAC8

	UNIQUE=%%NIKP+135246	;UNIQUE DATA TO IDENTIFY BLOCK

X	BLOCK		;-.TBLEN,,UNIQUE
X	UNITYP		;UNIQUE,,TYPE OF MESSAGE
X	XMTPPN		;XMITTERS PPN
X	CWAFLG		;.NE. 0 THEN IN [PASSIVE] CONNECT WAIT
X	CHKSUM		;FILE DATA CHECKSUM (CLOSE ONLY)
X	NODENM		;NODE NAME FOR NUMBER
X	FILBLK,.FOPPN+1	;FILOP. BLOCK (DEVICE, ETC.)
X	PTHBLK,.PTMAX	;FULL EXTENDED PATH BLOCK
X	LKEBLK,.RBMAX+1	;EXTENDED LOOKUP/ENTER BLOCK FOR FILE
X	UNILAS		;UNIQUE,,-UNIQUE (LAST PROTOCOL CHECK)

	X	.TBLEN,0	;LENGTH OF COMMUNICATIONS PROTOCOL BLOCK

X	BLKFLG		;-1 WHEN EXPECT START OF PROTOCOL BLOCK
X	COKFLG		;-1 IF PREMATURE EOF CAN BE HANDLED
X	TSKOPN,3	;TASK OPEN BLOCK (TSKXMT ONLY)
X	TSKOHD,3	;TASK OUTPUT HEADER
X	TSKIHD,3	;TASK INPUT HEADER
X	DSKOHD,3	;DISK OUTPUT HEADER
X	DSKIHD,3	;DISK INPUT HEADER

	X	PROTBL,0	;LENGTH OF THIS DATA BLOCK

	PRGEND
	TITLE	ERR	ERROR HANDLER

	SALL		;PRETTY LISTINGS

	SEARCH	TSKUNV,UUOSYM,MACTEN

	ENTRY	ERR		;ERROR PROCESSOR

	TWOSEG	400000

ERR::	EXCH	R1,0(P)		;SAVE R1 GET ERROR ADDRESS
	SKIPLE	S.DETA##	;ARE WE DETACHED?
	JRST	ERRET		;YES, DON'T OUTPUT ANYTHING
	SKIPG	S.RECV##	;ARE WE RUNNING PASSIVE RECEIVER?
	PUSHJ	P,TELERR##	;NO, MAKE SURE FILE IS KNOWN
	OUTSTR	[ASCIZ/? /]	;ERROR PREFIX
	OUTSTR	@.JBUUO##	;TYPE ERROR TEXT
	OUTSTR	[ASCIZ/
/]
ERRET:	POP	P,R1
	POPJ	P,
	PRGEND
TITLE	TSKSPX - - -  ROUTINES TO SEND A FILE FOR TSKSPL

	SALL		;PRETTY LISTINGS

	SEARCH	TSKUNV,UUOSYM,MACTEN

	ENTRY	TSKXMT		;SEND A FILE

	TWOSEG	400000

;	MODIFIABLE DATA

	RELOC	0

BLKBLK:	BLOCK	PROTBL
SUBTTL	MAIN

	RELOC	400000		;PURE CODE NOW

TSKXMT::PUSH	P,R1		;SAVE NODE NAME
	MOVEI	B,BLKBLK	;POINT TO MODIFIABLE DATA AREA
	PUSHJ	P,SETUPB##	;INIT DATA AREA
	 HALT	.		;CAN'T HAPPEN
	POP	P,NODENM(B)	;SETUP NODE NAME
	MOVE	R1,.MYPPN##	;WHO WE ARE
	MOVEM	R1,XMTPPN(B)	;TELL RECEIVER

;NOW SETUP FILE NAME/ETC. INFO

	MOVE	R1,OUOPN##	;OUTPUT DENSITY/ETC. (AS SPECIFIED BY USER)
	MOVEM	R1,FILBLK+.FOIOS(B)	;SET IN DATA BLOCK
	MOVE	R1,OUOPN##+1	;OUTPUT DEVICE (AS SPECIFIED BY USER)
	MOVEM	R1,FILBLK+.FODEV(B)	;SET IN DATA BLOCK
	MOVSI	R1,INFIL##	;INPUT LOOKUP BLOCK FROM MONITOR
	HRRI	R1,LKEBLK(B)	;OUR DATA BLOCK
	BLT	R1,LKEBLK+.RBMAX(B)	;COPY DATE/TIME/LENGTH ETC.
	MOVE	R1,OUFIL##+.RBCNT  ;/ERSUPERCEDE ETC.
	MOVEM	R1,LKEBLK+.RBCNT(B)  ;SET IN DATA BLOCK
	SKIPE	R1,OUFIL##+.RBPPN  ;OUTPUT DIRECTORY WORD
	JRST	TSKX02		;CHECK FOR PATH ADDRESS
	MOVSI	R1,.PTMAX-1	;LENGTH OF OUR PATH BLOCK
	HRRI	R1,PTHBLK(B)	;ADDRESS OF OUR PATH BLOCK
	SETOM	PTHBLK(B)	;-1 = READ DEFAULT PATH
		.CREF	.PTFRD	;CREF REFERENCE TO REAL FUNCTION
	PATH.	R1,		;ALWAYS GIVE RECEIVE AN EXPLICIT PATH
	 ERROR	[ASCIZ/PATH. failure/]
	SETZM	PTHBLK(B)	;CLEAR EXTRANEOUS BITS
	SETZM	PTHBLK+1(B)	;DITTO
	HRRZM	R1,LKEBLK+.RBPPN(B)	;TELL RECV TO USE PTHLBK BLOCK
	JRST	TSKX04		;CONTINUE FILLING DATA BLOCK
TSKX02:	MOVEM	R1,LKEBLK+.RBPPN(B)	;ASSUME UFD FOR MOMENT
	TLNE	R1,-1		;UFD OR EXTENDED PATH BLOCK?
	JRST	TSKX04		;UFD
	MOVS	R1,R1		;PATH BLOCK - GET FROM ADDRESS
	HRRI	R1,PTHBLK(B)	;GET TO ADDRESS
	BLT	R1,PTHBLK+.PTMAX-1(B)  ;COPY PATH BLOCK INTO DATA BLOCK

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

TSKX04:	MOVE	R1,OUFIL##+.RBNAM  ;OUTPUT FILENAME
	MOVEM	R1,LKEBLK+.RBNAM(B)	;SET IN DATA BLOCK
	HLLZ	R1,OUFIL##+.RBEXT  ;OUTPUT EXTENSION
	HLLM	R1,LKEBLK+.RBEXT(B)	;SET IN DATA BLOCK
	LDB	R0,[POINTR LKEBLK+.RBPRV(B),RB.MOD]  ;GET ORIGINAL DEVICE MODE
	DPB	R0,[POINTR FILBLK+.FOIOS(B),IO.MOD]  ;SO IS CREATED SAME WAY
	LDB	R1,[POINTR OUFIL##+.RBPRV,RB.PRV]  ;OUTPUT PROTECTION
	SKIPE	R1		;IF SPECIFIED
	DPB	R1,[POINTR LKEBLK+.RBPRV(B),RB.PRV]  ;SET IN DATA BLOCK
	SKIPE	R1,OUFIL##+.RBVER  ;/VERSION
	MOVEM	R1,LKEBLK+.RBVER(B)	;SET IN DATA AEA
	MOVE	R1,LKEBLK+.RBSIZ(B)	;FILE SIZE IN WORDS
	ADDI	R1,177		;ROUND UP TO NEAREST BLOCK
	LSH	R1,-7		;DEFAULT ESTIMATE OF FILE SIZE
	SKIPE	OUFIL##+.RBEST	;/ESTIMATE?
	MOVE	R1,OUFIL##+.RBEST  ;YES, USE USER'S EXPLICIT VALUE INSTEAD
	SKIPLE	S.ALLO##	;/ALLOCATE GIVEN?
	SETZ	R1,		;YES, IN THAT CASE NO ESTIMATE
	MOVEM	R1,LKEBLK+.RBEST(B)	;SET ESTIMATED FILE SIZE IN DATA AREA
	SKIPG	S.ALLO##	;/ALLOCATE SPECIFIED?
	SETZM	LKEBLK+.RBALC(B);NO, DON'T REQUIRE CONTIGUOUS ALLOCATION
	MOVX	R1,RP.DIR	;FILE-IS-DIRECTORY BIT
	TDNE	R1,LKEBLK+.RBSTS(B)  ;TRANSFERRING A DIRECTORY FILE?
	SETZM	LKEBLK+.RBSIZ(B);YES, THEN NO DATA!

;POSITION BUFFERS WHERE WE KNOW ABOUT THEM

	MOVEI	R1,$DSK		;DISK I/O CHANNEL
	MOVEI	R2,DSKIHD(B)	;INPUT HEADER
	MVHDR.	R1,		;MOVE BUFFER HEADER
	 ERROR	[ASCIZ/Can't move buffer headers/]
	MOVSI	R1,(POINT 36,)	;READ DISK IN "IMAGE" MODE
	MOVEM	R1,DSKIHD+1(B)	;SO TELL MONITOR

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;ESTABLISH COMMUNICATIONS WITH REMOTE PASSIVE RECEIVER

	MOVEI	R1,NTIOM	;TASK-TO-TASK I/O MODE
	SKIPLE	S.NBIO##	;USE NON-BLOCKING I/O?
	TXO	R1,UU.AIO	;YES
	MOVEM	R1,TSKOPN(B)	;SAVE IN OPEN BLOCK
	PUSHJ	P,GETTSK	;RETURNS TSKNN
	ERROR	[ASCIZ/Unable to find receiver node/]
	MOVEM	R1,TSKOPN+1(B)	;DEVICE NAME
	HRLI	R1,TSKOHD(B)	;TASK OUTPUT BUFFER RING HEADER
	HRRI	R1,TSKIHD(B)	;OUTPUT,,INPUT HEADER
	MOVEM	R1,TSKOPN+2(B)	;FINISH OFF TASK OPEN BLOCK
	MOVEI	P2,5		;TIMES TO TRY BEFORE GIVING UP

	OPEN	$TSK,TSKOPN(B)	;OPEN TASK DEVICE
	ERROR	[ASCIZ/Unable to OPEN receiver node/]

TSKX10:	MOVEI	R1,3		;LENGTH OF EXTENDED LOOKUP BLOCK
	SETZB	R2,R4		;NO PATH OR EXTENSION
	MOVX	R3,NIKNM1	;AND OUR TASK NAME
	LOOKUP	$TSK,R1		;SET FOR READING
	 ERROR	[ASCIZ/Impossible task LOOKUP failure/]

	MOVEI	R1,3		;LENGTH OF EXTENDED LOOKUP BLOCK
	SETZB	R2,R4		;NO PATH OR EXTENSION
	MOVX	R3,NIKNM1	;AND OUR TASK NAME
	ENTER	$TSK,R1		;SET FOR WRITING
	CAIA			;HANDLE ERROR
	JRST	TSKX20		;GOT REMOTE, GO TRANSFER FILE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	MOVEI	R1,3		;LENGTH OF EXTENDED LOOKUP BLOCK
	SETO	R2,		;TRY FOR A /ANYPPN'ED RECEIVER
	MOVX	R3,NIKNM2	;WITH AN ANYNIK NAME
	SETZ	R4,		;NO EXTENSION
	LOOKUP	$TSK,R1		;SET FOR READING
	 ERROR	[ASCIZ/Impossible task LOOKUP failure/]

	MOVEI	R1,3		;LENGTH OF EXTENDED ENTER BLOCK
	SETO	R2,		;TRY FOR A /ANYPPN'ED RECEIVER
	MOVX	R3,NIKNM2	;WITH AN ANYNIK NAME
	SETZ	R4,		;NO EXTENSION
	ENTER	$TSK,R1		;SET FOR WRITING
	CAIA			;CAN'T
	JRST	TSKX20		;GOT IT

;NO NIK AT DESTINATION NODE WILLING TO ACCEPT US

	SOJE	P2,TSKX19	;GIVE UP AFTER A FEW TRIES
	MOVEI	R1,2		;A COUPLE SECONDS
	SKIPG	P2		;ARE WE WAITING?
TSKX17:	MOVEI	R1,^D15		;YES, LESSEN LOAD ON NETWORK
	SLEEP	R1,		;TO SEE IF ANYONE APPEARS
	JRST	TSKX10		;AND TRY AGAIN

TSKX19:	SKIPG	S.WAIT##	;/WAIT SPECIFIED?
	ERROR	[ASCIZ/Unable to ENTER receiver node/]
	OUTSTR	[ASCIZ/% Unable to ENTER receiver node, waiting . . .
/]
	JRST	TSKX17		;WAIT AS LONG AS NEEDED
;CONTINUED FROM PREVIOUS PAGE

;$DSK AND $TSK ARE OPEN AND READY
;SEND INITIAL CONTACT TO REMOTE

TSKX20:	INBUF	$TSK,2		;ONLY TWO INPUT BUFFERS
	OUTBUF	$TSK,1		;ONLY ONE OUTPUT BUFFER
	MOVEI	R1,TK.INI	;INITIAL CONTACT TYPE
	PUSHJ	P,SNDBLK##	;SEND BLKBLK TO REMOTE
	 POPJ	P,		;I/O ERROR MESSAGE ALREADY ISSUED

;	WAIT FOR CONTACT VERIFING RESPONSE

	MOVE	P1,LKEBLK+.RBSIZ(B)	;GET LENGTH OF FILE IN WORDS
	PUSHJ	P,RCVBLK##	;RECEIVE ACKNOWLEDGEMENT FROM REMOTE
	 POPJ	P,		;I/O ERROR MESSAGE ALREADY ISSUED

	CAIE	R1,TK.EFL	;DID REMOTE ENTER FAIL?
	JRST	TSKX24		;IT DIDN'T EXPLICITLY FAIL
	MOVSI	R1,LKEBLK(B)	;ADDRESS OF FAILED ENTER BLOCK
	IORI	R1,OUFIL##	;ADDRESS OF ONE THAT E.SCL KNOWS ABOUT
	BLT	R1,OUFIL##+.RBMAX  ;PRETEND WE DID ENTER THERE
	MOVEI	R1,PTHBLK(B)	;ADDRESS OF PATH OF FILE
	MOVEM	R1,OUFIL##+.RBPPN  ;FINISH FAKING WILD
	HRRZ	R1,OUFIL##+.RBEXT  ;ENTER ERROR CODE
	CAIE	R1,ERDNA%	;DEVICE UNAVAILABLE?
	CAIN	R1,ERNSD%	;OR NONEXISTENT?
	SETZM	OUFIL##+.RBDEV	;YES, CLEAR LOOKUP'S STRUCTURE NAME
				; (PART OF FAKING OUT WILD)
	PUSHJ	P,TELERR##	;MAKE SURE USER KNOWS WHICH FILE
	PJRST	E.SCL##		;TYPE OUT ENTER FAILURE

TSKX24:	CAIE	R1,TK.EOK	;DID ENTER SUCCEED
	ERROR	[ASCIZ/Incorrect response from receiver./]
	MOVEM	P1,LKEBLK+.RBSIZ(B)	;PUT IT BACK SINCE RECEIVE KRUMPED IT.

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;FILE OPEN CORRECTLY AT BOTH ENDS
;COPY FROM $TSK TO $DSK

TSKX40:	SETZM	CHKSUM(B)	;MAKE SURE VIRGIN CHECKSUM
	JUMPE	P1,CLOS		;IF REALLY NO DATA JUST CLOSE OFF
	PUSHJ	P,SETRAI##	;SET INITIAL PERCENTAGE

TSKX50:	PUSHJ	P,DSKINP##	;READ A WORD FROM INPUT FILE
	 POPJ	P,		;ERROR MESSAGE ALREADY ISSUED
	EXCH	R1,CHKSUM(B)	;THIS
	ROT	R1,1		; ALGORITHM
	ADD	R1,CHKSUM(B)	;  FROM
	EXCH	R1,CHKSUM(B)	;   DIRECT
	PUSHJ	P,TSKOUT##	;SEND THE WORD TO THE REMOTE RECEIVER
	 POPJ	P,		;ERROR MESSAGE ALREADY ISSUED
	TRNN	P1,77		;ONLY CHECK AND SET PERCENTAGE
	PUSHJ	P,SETRAT##	;EVERY SO OFTEN.
	SOJG	P1,TSKX50	;LOOP FOR ENTIRE FILE

TSKX60:	PUSHJ	P,DSKINP##	;TRY READING ONE MORE WORD
	CAIA			;EOF IS EXPECTED
	 OUTSTR	[ASCIZ/% File is longer than expected, file truncated./]
	PUSHJ	P,TSKFRC##	;FORCE OUT LAST BUFFER
	 POPJ	P,		;ERROR MESSAGE ALREADY ISSUED
CLOS:	HLRZ	P1,CHKSUM(B)	;LH
	HRRZ	R2,CHKSUM(B)	;RH
	ADD	R2,P1		;COMBINE HALVES
	HLRZ	P1,R2		;GET POSSIBLE CARRY
	ADDI	P1,(R2)		;P1 := 18-BIT CHECKSUM, SAME AS DIRECT

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	CLOSE	$DSK,		;CLOSE DISK FILE

	MOVE	R1,['CHKW  ']	;INDICATE CHECKING
	SKIPLE	S.PERC##	;ONLY IF /PERCENT
	SETNAM	R1,		;CHANGE NAME

;FILE COPIED - WAIT FOR CONFIRM

	PUSHJ	P,RCVBLK##	;READ RESPONSE FROM REMOTE
	 POPJ	P,		;I/O ERROR MESSAGE ALREADY ISSUED
	CAIE	R1,TK.COK	;CLOSE AND COMPLETE OK?
	 ERROR	[ASCIZ/Incorrect CLOSE response received/]

;VERIFY FILE GOT ACROSS OK

	CAME	P1,CHKSUM(B)	;DOES OUR CHECKSUM MATCH RECEIVERS?
	 ERROR	[ASCIZ/Checksums do not match!/]

;NOW SEE IF ANY TRAILING DATA MATERIALIZED

	PUSHJ	P,TSKIEF##	;READ PAST LOGICAL EOF

;CLEAN UP

;**********************************************************************
;
;	EMPIRICALLY, I HAVE OBSERVED THAT WHEREAS A CLOSE WILL
;	OCCAISIONALLY IME A 6.03? MONITOR A RESDV. WILL NOT.
;	THEREFORE:
;
;	CLOSE	$TSK,		;FINISH UP CLOSE
	MOVEI	R1,$TSK		;TASK I/O CHANNEL
	RESDV.	R1,		;ZAP IT DEAD
	 ERROR	[ASCIZ/RESDV. failed for $TSK?????????/]
;
;**********************************************************************

	MOVX	R1,NIKNM1	;OUR RIGHTFUL NAME
	SKIPLE	S.PERC##	;ONLY IF /PERCENT
	SETNAM	R1,		;CHANGE NAME BACK
	JRST	.POPJ1##	;SUCCESSFUL RETURN
SUBTTL	GETTSK	- - -  TASK TO CONTACT
COMMENT^
	GETTSK
			ROUTINE RETURNS THE DEVICE TO OUTPUT TO.
	CALL:
		PUSHJ	P,GETTSK
			ERROR RETURN
		NORMAL RETURN
			W/ R1= 'TSKxx0'  IN SIXBIT
^
GETTSK:	SKIPN	R2,NODENM(B)	;NODE NAME REQUIRED
	ERROR	[ASCIZ/No node name specified/]
	MOVEI	R1,2		;LENGTH FOR NODE UUO
	MOVE	R0,[2,,1]	;FUNCTION,,ADDR OF PARAM
	NODE.	R0,		;LOCATE NODE NUMBER
	ERROR	[ASCIZ/Unable to locate node/]
	TLNE	R0,777777	;MAKE SURE WE GOT NUMBER
	ERROR	[ASCIZ/Unable to locate node/]
	MOVE	R1,R0
	LSH	R0,3
	IOR	R1,R0
	TRZ	R1,777070
	LSH	R1,6
	ADD	R1,['TSK000']	;MAKE SIXBIT TSKnn0
	JRST	.POPJ1##	;SUCCESSFUL RETURN

	PRGEND
	TITLE	RECV	PASSIVE RECEIVER MODULE OF NIK

	SALL		;PRETTY LISTINGS

	SEARCH	TSKUNV,UUOSYM,MACTEN

	ENTRY	RECV

	TWOSEG	400000

	RELOC	0

PDLL=100
PDL:	BLOCK	PDLL

	RELOC	400000

RECV::	SKIPG	S.DETA##	;IF USER SAID /DETACH
	JRST	CONT		;HE DIDN'T
	OUTSTR	[ASCIZ/Receiver active...detaching...job /]
	PJOB	R0,
	IDIVI	R0,^D10
	ADDI	R0,"0"
	ADDI	R1,"0"
	OUTCHR	R0
	OUTCHR	R1
	OUTSTR	[ASCIZ/
./]
	SETOM	R0,
	GETLCH	R0,
	HRLZS	R0
	ATTACH	R0,
	CAIA			;DETACH FAILED
	JRST	CONT		;ALL IS NORMAL SO FAR
	SETOM	S.DETA##	;FLAG WE ARE ***NOT*** DETACHED
	OUTSTR	[ASCIZ/Could not detach.
/]

CONT:	MOVE	P,[-PDLL,,PDL]
	RESET			;CLEAR THE WORLD
	PUSH	P,[CONT]
	PUSHJ	P,TSKRCV##
	JFCL
	MOVE	R1,['NIK   ']	;OUR NAME
	SKIPLE	S.PERC##	;/PERCENTAGES?
	SETNAM	R1,		;YES, SET BACK TO REAL NAME
	JRST	CONT		;TRY FOR MORE
	PRGEND
TITLE	TSKSPR - - -  TSKSPL FILE RECEIVER

	SALL		;PRETTY LISTINGS

	SEARCH	TSKUNV,UUOSYM,MACTEN

	ENTRY	TSKRCV

	TWOSEG	400000

	RELOC	0

;MODIFIED DATA BLOCKS

BLKBLK:	BLOCK	PROTBL
SUBTTL	MAIN

	RELOC	400000

TSKRCV::MOVEI	B,BLKBLK	;SETUP MODIFIABLE DATA BLOCK
	PUSHJ	P,SETUPB##	;SETUP AND INIT BLOCK
	 HALT	.		;IMPOSSIBLE

	MOVEI	R0,NTIOM	;DATA MODE
	SKIPLE	S.NBIO##	;USE NON-BLOCKING TSK: I/O?
	TXO	R0,UU.AIO	;YES
	HRLZI	R1,'TSK'	;DEVICE NAME
	HRLZI	R2,TSKOHD(B)	;OUTPUT HEADER,,0
	HRRI	R2,TSKIHD(B)	;OUTPUT HEADER,,INPUT HEADER

	OPEN	$TSK,R0		;OPEN DEVICE
	ERROR	[ASCIZ/Unable to OPEN device TSK:/]

	INBUF	$TSK,4		;LOTS OF INPUT BUFFERING
	OUTBUF	$TSK,1		;BUT STILL ONLY ONE OUTPUT BUFFER

	MOVEI	R1,3		;LENGTH OF EXTENDED LOOKUP BLOCK
	SETZB	R2,R4		;NO PATH OR EXTENSION
	SKIPLE	S.ANYP##	;/ANYPPN?
	SKIPA	R3,[NIKNM2]	;YES, USE ANYNIK NAME
	MOVX	R3,NIKNM1	;NO, OUR TASK NAME
	SKIPLE	S.ANYP##	;/ANYPPN?
	SETO	R2,		;YES, ACCEPT FROM [777777,777777] THEN
	LOOKUP	$TSK,R1		;READ FROM XMITER
	ERROR	[ASCIZ/Unable to LOOKUP transmitter node/]

	SETOM	CWAFLG(B)	;SET LONG WAIT FLAG
	PUSHJ	P,RCVBLK##	;WAIT FOR ACTIVE TASK TO CONNECT
	 POPJ	P,		;I/O ERROR MESSAGE ALREADY ISSUED
	SETZM	CWAFLG(B)	;CLEAR LONG WAIT FLAG
	CAIE	R1,TK.INI	;INTRODUCTION?
	ERROR	[ASCIZ/Invalid greetings block./]

	MOVEI	R1,3		;LENGTH OF EXTENDED LOOKUP BLOCK
	SETZB	R2,R4		;NO PATH OR EXTENSION
	SKIPLE	S.ANYP##	;/ANYPPN?
	SKIPA	R3,[NIKNM2]	;YES, USE ANYNIK NAME
	MOVX	R3,NIKNM1	;NO, OUR TASK NAME
	SKIPLE	S.ANYP##	;/ANYPPN?
	SETO	R2,		;YES, I/O FOR [777777,777777]
	ENTER	$TSK,R1		;WRITE TO XMITER
	ERROR	[ASCIZ/Unable to ENTER transmitter node/]

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;ACCESS FILE ACCORDING TO BLOCK JUST RECEIVED

TSKR10:	MOVE	P1,LKEBLK+.RBSIZ(B)  ;GET NUMBER OF WORDS WRITTEN IN OLD FILE
	HRLZI	R1,DSKOHD(B)	;OUTPUT HEADER
	MOVEM	R1,FILBLK+.FOBRH(B)  ;SET IN FILOP. BLOCK
	SKIPE	R1,LKEBLK+.RBPPN(B)  ;GET DIRECTORY WORD (IF ANY)
	TLNE	R1,-1		;WAS, UFD OR PATH BLOCK
	CAIA			;UFD, LEAVE IT ALONE
	MOVEI	R1,PTHBLK(B)	;PATH, GET OUR ADDRESS FOR SAME
	MOVEM	R1,LKEBLK+.RBPPN(B)  ;AND SET IT IN THE EXTENDED ENTER BLOCK

;***********************************************************************
;
;	ON A CREATE/SUPERCEDE ENTER THE MONITOR, RATHER THAN RETURNING
;	ALL THE "LOOKUP" INFORMATION FOR THE NEW FILE (E.G., .RBSTS
;	WHICH NIK NEEDS TO SEE IF THE FILE IS A DIRECTORY FILE) ZEROES
;	MOST OF THE BLOCK - IN PARTICULAR IT DOES RETURN .RBPPN/PATH,
;	.RBEXT (TIME FIELDS), .RBPRV, .RBALC, AND .RBDEV; HOWEVER IT
;	DOES ***NOT*** RETURN .RBSTS! THEREFORE NIK MUST ITSELF "PRE-
;	SERVE" .RBSTS ACCROSS THE ENTER, AND HOPE FOR THE BEST . . .
;
;***********************************************************************

	MOVE	P2,LKEBLK+.RBSTS(B)  ;SAVE .RBSTS ACCROSS ENTER
	SKIPG	S.ANYP##	;/ANYPPN?
	TDZA	R1,R1		;NO
	MOVE	R1,XMTPPN(B)	;YES
	MOVEM	R1,FILBLK+.FOPPN(B)  ;DO ENTER ON BEHALF OF . . .
	MOVEI	R1,LKEBLK(B)	;ADDRESS OF ENTER BLOCK
	MOVEM	R1,FILBLK+.FOLEB(B)  ;SET IN FILOP. BLOCK
	MOVE	R1,[400000+$DSK,,.FOWRT]  ;CHANNEL,,FUNCTION=CREATE/SUPERCEDE
	MOVEM	R1,FILBLK+.FOFNC(B)  ;SET IN FILOP. BLOCK
	MOVSI	R1,.FOPPN+1	;LENGTH OF FILOP. BLOCK
	HRRI	R1,FILBLK(B)	;ADDRESS OF FILOP. BLOCK
	FILOP.	R1,		;TRY TO CREATE THE FILE
	CAIA			;ENTER FAILED
	JRST	TSKR14		;FILE SUCCESSFULLY ENTERED
	HRRM	R1,LKEBLK+.RBEXT(B)  ;ERNSD% NOT RETURNED IN ENTER BLOCK
	MOVEI	R1,TK.EFL	;ENTER FAILURE
	PUSHJ	P,SNDBLK##	;TELL REMOTE
	 JFCL			;I/O ERROR MESSAGE ALREADY ISSUED
	ERROR	[ASCIZ/Unable to create output file/]

TSKR14:	SKIPN	LKEBLK+.RBSTS(B);ANYTHING THERE (BUG FIXED?)?
	MOVEM	P2,LKEBLK+.RBSTS(B)  ;ASSUME IT'S WRONG (WHAT ELSE CAN I DO?)
	SETSTS	$DSK,.IOIMG	;ENSURE CHANNEL IN A KNOWN STATE (I.E.,
				;  OPEN MIGHT HAVE BEEN IN DUMP MODE).
	MOVSI	R1,(POINT 36,0,35)  ;WE ARE DOING "IMAGE" 36-BIT BYTES
	MOVEM	R1,DSKOHD+1(B)	;MAKE SURE MONITOR KNOWS!
	MOVEI	R1,TK.EOK	;MARK ENTER WORKED OK
	PUSHJ	P,SNDBLK##	;TELL REMOTE ALL IS OK SO FAR
	 POPJ	P,		;I/O ERROR MESSAGE ALREADY ISSUED

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;FILE OPEN AT BOTH ENDS

TSKR40:	SETZM	CHKSUM(B)	;MAKE SURE VIRGIN CHECKSUM
	MOVEM	P1,LKEBLK+.RBSIZ(B)  ;SAVE TOTAL SIZE
	JUMPE	P1,CLOS		;EMPTY JUST CLOSE IT
	PUSHJ	P,SETRAI##	;START OFF PERCENTAGES

TSKR50:	PUSHJ	P,TSKINP##	;GET A WORD
	 POPJ	P,		;I/O ERROR MESSAGE ALREADY ISSUED
	EXCH	R1,CHKSUM(B)	;THIS
	ROT	R1,1		; ALGORITM
	ADD	R1,CHKSUM(B)	;  FROM
	EXCH	R1,CHKSUM(B)	;   DIRECT
	PUSHJ	P,DSKOUT##	;AND SEND IT TO THE OUTPUT FILE
	 POPJ	P,		;I/O ERROR MESSAGE ALREADY ISSUED
	TRNN	P1,77		;ONLY DO PERCENTAGE STUFF
	PUSHJ	P,SETRAT##	;EVERY SO OFTEN
	SOJG	P1,TSKR50	;LOOP FOR ENTIRE FILE

CLOS:	CLOSE	$DSK,
	STATZ	$DSK,IO.ERR	;ANY LAST MOMENT ERRORS?
	 ERROR	[ASCIZ\I/O error CLOSEing output file\]
	MOVE	R0,['CHKW  ']
	SKIPLE	S.PERC##	;ONLY IF /PERCENT
	SETNAM	R0,
	HLRZ	R1,CHKSUM(B)	;LH
	HRRZ	R2,CHKSUM(B)	;RH
	ADD	R2,R1		;COMBINE HALVES
	HLRZ	R1,R2		;GET POSSIBLE CARRY
	ADDI	R1,(R2)		;18-BIT CHECKSUM JUST LIKE DIRECT
	MOVEM	R1,CHKSUM(B)	;STUFF IN PROTOCOL BLOCK

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;TRANSFER COMPLETE - CONFIRM 

	MOVEI	R1,TK.COK	;TYPE FOR COMPLETE
	PUSHJ	P,SNDBLK##	;TELL REMOTE WE'RE DONE
	 JFCL			;I/O ERROR MESSAGE ALREADY ISSUED

;**********************************************************************
;
;	EMPIRICALLY, I HAVE OBSERVED THAT WHEREAS A CLOSE WILL
;	OCCAISIONALLY IME A 6.03? MONITOR A RESDV. WILL NOT.
;	THEREFORE:
;
;	CLOSE	$TSK,		;FINISH UP CLOSE
	MOVEI	R1,$TSK		;TASK I/O CHANNEL
	RESDV.	R1,		;ZAP IT DEAD
	 ERROR	[ASCIZ/RESDV. failed for $tsk?????????/]
;
;**********************************************************************

;	MOVSI	R0,'NIK'	;OUR NAME
;	SKIPLE	S.PERC##	;ONLY IF /PERCENT
;	SETNAM	R0,
	JRST	.POPJ1##	;SUCCESSFUL RETURN

	PRGEND
	TITLE	DSKINP	HANDLE DISK INPUT

	SALL

	SEARCH	TSKUNV,UUOSYM,MACTEN

	ENTRY	DSKINP

	TWOSEG	400000

;DSKINP  --  READ DATA FROM INPUT FILE (DISK PRESUMED BUT NOT REQUIRED)
;CALL IS:
;
;	PUSHJ	P,DSKINP
;	 ERROR/EOF
;	NORMAL
;
;ON AN I/O ERROR, AN ERROR MESSAGE IS ISSUED AND RETURN IS CPOPJ0.
;
;ON EOF NO MESSAGE IS ISSUED AND RETURN IS CPOPJ0.
;
;NORMAL RETURN IS CPOPJ1 WITH NEXT 36-BIT WORD IN R1.

DSKINP::SOSGE	DSKIHD+2(B)	;ANY DATA STILL IN THIS BUFFER?
	 JSP	J,DSKIN8	;NO, READ NEXT BUFFER
	ILDB	R1,DSKIHD+1(B)	;READ NEXT BYTE
	JRST	.POPJ1##	;SUCCESSFUL RETURN

DSKIN8:	IN	$DSK,		;ASK MONITOR FOR NEXT BUFFER
	JRST	-2(J)		;CONTINUE ABOVE
	STATO	$DSK,IO.EOF	;ERROR - IS IT END OF FILE?
	ERROR	[ASCIZ/Data file input error./]
	POPJ	P,		;EOF, JUST RETURN SANS DATA

	PRGEND
	TITLE	DSKOUT	HANDLE DISK OUTPUT

	SALL

	SEARCH	TSKUNV,UUOSYM,MACTEN

	ENTRY	DSKOUT

	TWOSEG	400000

;DSKOUT  --  WRITE DATA TO OUTPUT (DISK PRESUMED BUT NOT REQUIRED)
;CALL IS:
;
;	MOVX	R1,<DATA-WORD>
;	PUSHJ	P,DSKOUT
;	 ERROR
;	NORMAL
;
;WHERE <DATA-WORD> IS THE 36-BIT "BYTE" OF OUTPUT DATA
;
;ON I/O ERROR ERROR MESSAGE WILL BE ISSUED AND NON-SKIP RETURN TAKEN.
;
;SUCCESSFUL RETURN IS CPOPJ1

DSKOUT::SOSGE	DSKOHD+2(B)	;ROOM IN BUFFER?
	 JSP	J,DSKOU8	;NO, GET ANOTHER BUFFER
	IDPB	R1,DSKOHD+1(B)	;STUFF DATA WORD IN OUTPUT BUFFER
	JRST	.POPJ1##	;SUCCESSFUL RETURN

DSKOU8:	OUT	$DSK,		;ASK MONITOR FOR NEXT BUFFER
	JRST	-2(J)		;CONTINUE ABOVE
	ERROR	[ASCIZ/Data file output error/]

	PRGEND
TITLE	TSKCOM - - - COMMON ROUTINES FOR TSKSPL ROUTINES

	SALL		;PRETTY LISTING

SUBTTL	PROTOTYPE COMMON BLOCK

	SEARCH	TSKUNV,UUOSYM,MACTEN

	ENTRY	SETUPB

	TWOSEG	400000

COMMENT^
	SETUPB
		THIS ROUTINE USED TO SETUP THE BASE
		REGISTER AND INITIALIZE THE COMMON DATA BLOCK.
	CALL:
		W/	B = ADDRESS OF DATA BLOCK
		PUSHJ	P,SETUPB
		  ERROR RETURN
		NORMAL RETURN
^
SETUPB::SETZM	(B)		;FIRST CLEAR THE BLOCK
	MOVSI	R1,(B)		;MAKE BLT POINTER
	HRRI	R1,1(B)		;TO DATA BLOCK
	BLT	R1,PROTBL-1(B)	;CLEAR OUT BLOCK
	MOVE	R1,[-.TBLEN,,UNIQUE] ;FIRST WORD
	MOVEM	R1,BLOCK(B)	;INIT LENGTH OF PROTOCOL BLOCK
	HRLZM	R1,UNITYP(B)	;SECOND UNIQUE "BYTE"
	MOVEI	R1,.RBMAX	;LENGTH OF LOOKUP/ENTER BLOCK
	MOVEM	R1,LKEBLK(B)	;SET IT UP
	MOVE	R1,[UNIQUE,,-UNIQUE]  ;FINAL FORMAT VERIFIER
	MOVEM	R1,UNILAS(B)	;END OF PROTOCOL BLOCK
	JRST	.POPJ1##	;SUCCESSFUL RETURN
	SUBTTL	BLOCK INPUT AND OUTPUT ROUTINES

;SNDBLK  --  SEND A COMMUNICATIONS PROTOCOL BLOCK
;CALL IS:
;
;	MOVEI	R1,<CODE>
;	PUSHJ	P,SNDBLK
;	 ERROR
;	NORMAL
;
;WHERE <CODE> IS ONE OF THE TK.* MESSAGE TYPES.
;
;THIS ROUTINE WILL TRANSMIT THE DATA BLOCK POINTED TO BY REGISTER B
;TO THE REMOTE TASK.
;
;ON A TASK OUTPUT ERROR AN ERROR WILL BE ISSUED AND THE NON-SKIP
;RETURN TAKEN.
;
;SUCCESSFUL RETURN IS CPOPJ1.

SNDBLK::HRRM	R1,UNITYP(B)	;SET MESSAGE TYPE IN DATA BLOCK
	HLLZ	R4,BLOCK(B)	;GET USEFUL DATA BLOCK LENGTH
	HRRI	R4,BLOCK(B)	;AND ITS ADDRESS
	SETOM	BLKFLG(B)	;TELL I/O WE ARE STARTING A BLOCK

SNDBL4:	MOVE	R1,(R4)		;GET NEXT DATA WORD
	PUSHJ	P,TSKOUT	;SEND ON ITS WAY
	 POPJ	P,		;I/O ERROR MESSAGE ALREADY ISSUED
	AOBJN	R4,SNDBL4	;LOOP FOR ENTIRE BLOCK

	PUSHJ	P,TSKFRC	;FLUSH ANY PARTIAL DATA LEFT
	 POPJ	P,		;I/O ERROR MESSAGE ALREADY ISSUED
	JRST	.POPJ1##	;TAKE SUCCESSFUL RETURN
;RCVBLK  --  RECEIVE A COMMUNICATIONS PROTOCOL BLOCK
;CALL IS:
;
;	PUSHJ	P,RCVBLK
;	 ERROR
;	NORMAL
;
;ON A TASK INPUT ERROR AN ERROR MESSAGE WILL HAVE BEEN ISSUED
;AND THE NON-SKIP RETURN TAKEN.
;
;SUCCESSFUL RETURN IS CPOPJ1 WITH THE NEW COMMUNICATIONS PROTOCOL
;BLOCK STORED IN THE DATA BLOCK POINTED TO BY REGISTER B. THE MES-
;SAGE TYPE (TK.*) IS RETURNED IN REGISTER R1.

RCVBLK::SETOM	BLKFLG(B)	;TELL I/O WE ARE STARTING A BLOCK
	PUSHJ	P,TSKINP	;READ IN FIRST WORD
	 POPJ	P,		;I/O ERROR MESSAGE ALREADY ISSUED
	TRC	R1,UNIQUE	;CHECK FOR UNIQUE IN RH
	TRNE	R1,-1		;SHOULD BE 0 IF CORRECT FORMAT
	 ERROR	[ASCIZ/Communications protocol version skew/]
	CAME	R1,[-.TBLEN,,0]	;IS PROTOCOL BLOCK THE RIGHT SIZE?
	ERROR	[ASCIZ/Communications protocol block size error./]
	TRC	R1,UNIQUE	;RESTORE UNIQUE CODE
	MOVEM	R1,BLOCK(B)	;SAVE START OF BLOCK
	PUSHJ	P,TSKINP	;READ SECOND WORD
	 POPJ	P,		;I/O ERROR MESSAGE ALREADY ISSUED
	TLC	R1,UNIQUE	;CHECK FOR UNIQUE IN LH
	TLNE	R1,-1		;SHOULD BE 0 IF CORRECT FORMAT
RCVBL2:	 ERROR	[ASCIZ/Communications protocol block screwed up/]
	TLC	R1,UNIQUE	;RESTORE UNIQUE CODE
	MOVEM	R1,UNITYP(B)	;STORE UNIQUE,,TYPE WORD
	MOVSI	R4,-<.TBLEN-2>	;MAKE AOBJN POINTER
	HRRI	R4,2(B)		;FOR REST OF PROTOCOL BLOCK

;**********************************************************************
;
;	7.01 LOAD 350/351/352 WILL RETURN EOF TO NIK BEFORE THE DATA
;	WHICH PRECEDED THE CLOSE. THEREFORE, LEARN TO IGNORE EOF

	ANDI	R1,-1		;REDUCE TO TYPE WORD
	CAIN	R1,TK.COK	;CLOSE COMPLETE (WITH CHECKSUM)?
	SETOM	COKFLG(B)	;YES, HANDLE 352'S PREMATURE EOF
	SETOM	CHKSUM(B)	;MAKE SURE NO EXTRANEOUS CHECKSUMS

;
;**********************************************************************

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

RCVBL4:	PUSHJ	P,TSKINP	;READ IN ANOTHER WORD
	 JRST	RCVBL6		;GO CHECK OUT ERROR
	MOVEM	R1,(R4)		;AND STASH IT IN DATA BLOCK
	AOBJN	R4,RCVBL4	;LOOP FOR ENTIRE PROTOCOL BLOCK
	CAME	R1,[UNIQUE,,-UNIQUE]  ;FINAL FORMAT VERIFICATION
	JRST	RCVBL2		;FORMAT ERROR (TSKSER PROBABLY TRASHED US)
RCVBL5:	SETZM	COKFLG(B)	;FLAG NO MORE
	HRRZ	R1,UNITYP(B)	;RETURN R1 := MESSAGE TYPE
	JRST	.POPJ1##	;NO, SUCCESSFUL RETURN

RCVBL6:	SKIPE	COKFLG(B)	;READY FOR PREMATURE EOF?
	STATO	$TSK,IO.EOF	;AND IS THIS EOF OR ERROR
	 POPJ	P,		;TRUE DEATH
	BITCH	<% Premature task channel EOF>
	JRST	RCVBL5		;RETURN AND HOPE FOR BEST . . .
SUBTTL	TASK INPUT AND OUTPUT ROUTINES

;TSKINP  --  RETURN A WORD FROM REMOTE TASK
;CALL IS:
;
;	PUSHJ	P,TSKINP
;	 ERROR
;	NORMAL
;
;RETURNS NEXT WORD FROM REMOTE TASK IN R1

TSKINP::

IFE	NTIOM-.IOASC,<
	MOVE	R0,[POINT 6,R1]	;6 6-BIT BYTES = ONE -10 WORD
TSKIN2:	SOSGE	TSKIHD+2(B)	;GOT ANY TASK DATA?
	JSP	J,TSKIN8	;NO, GO REQUEST ANOTHER BUFFER
	ILDB	CHR,TSKIHD+1(B)	;YES, NEXT INPUT SEVEN-BIT BYTE
	TRZN	CHR,100		;VALID FILE DATA?
	JRST	TSKIN4		;NO, CHECK SPECIAL CODES
	AOSN	BLKFLG(B)	;WERE WE EXPECTING A PROTOCOL BLOCK?
	 ERROR	[ASCIZ/Didn't receive expected protocol block/]
	IDPB	CHR,R0		;SLIP IN THIS BYTE
	TLNE	R0,770000	;MADE A WHOLE WORD YET?
	JRST	TSKIN2		;NO, LOOP BACK FOR REST OF WORD
	JRST	.POPJ1##	;RETURN WITH WORD IN R1

TSKIN4:	CAIN	CHR,77		;RANDOM FILLER?
	JRST	TSKIN2		;YES, JUST IGNORE IT
	CAIN	CHR,76		;BLOCK HEADER?
	JRST	TSKIN5		;YES, MAKE SURE WE EXPECTED IT
	CAIN	CHR,75		;START OF BUFFER?
	JRST	TSKIN6		;YES, BUFFERS SKEWED
	SKIPE	CHR		;A ZERO BYTE?
	 BITCH	<% Zero byte received from TSKSER>
	SKIPN	CHR		;A JUNK BYTE?
	 BITCH	<% Junk byte received from TSKSER>
	JRST	TSKIN2		;KEEP LOOPING

TSKIN5:	AOSE	BLKFLG(B)	;MAKE SURE WE WERE EXPECTING A PROTOCOL BLOCK
	 ERROR	[ASCIZ/Unexpected protocol block received/]
	JRST	TSKIN2		;WE WERE, ALL IS WELL (SO FAR)

TSKIN6:	BITCH	<% Buffer skew from TSKSER>
	JRST	TSKIN2		;SEE WHAT ELSE IS AROUND
> ;END OF IFE NTIOM-.IOASC
;STILL TSKINP::

IFE	NTIOM-.IOIMG,<
	SOSGE	TSKIHD+2(B)	;GOT ANY TASK DATA?
	JSP	J,TSKIN8	;NO, GO REQUEST ANOTHER BUFFER
	ILDB	R1,TSKIHD+1(B)	;GET WORD
	JRST	.POPJ1##	;RETURN WITH WORD IN R1
> ;END OF IFE NTIOM-.IOIMG

;COMMON TASK INPUT ROUTINE

TSKIN8:	IN	$TSK,		;READ NEXT BUFFER
	JRST	TSKIN9		;VERIFY NEW BUFFER
	STATZ	$TSK,IO.ERR	;I/O GOODNESS?
	ERROR	[ASCIZ/Task input error/]
	STATZ	$TSK,IO.EOF	;I/O END OF FILE?
	JRST	[SKIPN	COKFLG(B)  ;EOF OK?
		ERROR	[ASCIZ/Premature task channel EOF/]
		POPJ	P,]	;IGNORE EOF
	SKIPG	S.NBIO##	;EXPECTING NON-BLOCKING I/O?
	BITCH	<% Blocking I/O gave non-blocking return>

;**********************************************************************
;
;	7.01 LOAD 332 HAS A TENDENCY TO PUT JOBS IN EW STATE AND
;	THEN FORGET ABOUT THEM - SO WE DO NON-BLOCKING I/O
;	AND JUST KEEP TRYING TILL SOMETHING EXCITING HAPPENS
;

	PUSH	P,R1		;NEED A FREE AC
	MOVX	R1,<HB.RIO+^D32>  ;WAIT TWO TICKS OR TILL INPUT READY
	SKIPE	CWAFLG(B)	;LONG WAIT FLAG?
	ADDI	R1,^D2000	;YES, WAIT TWO SECONDS INSTEAD
				; (I'D WAIT LONGER, BUT TOPS-10 WON'T
				;  WAKE ME UP ON INPUT READY, SO . . .)
	HIBER	R1,		;TWIDDLE OUR THUMBS AWHILE
	 BITCH	<% HIBER for input failed>
	POP	P,R1		;RESTORE AC
	JRST	TSKIN8		;AND TRY ANOTHER IN

;
;**********************************************************************
TSKIN9:	SKIPLE	TSKIHD+2(B)	;GOT ANY DATA?
	JRST	TSKIP2		;YES
	BITCH	<%Null buffer received from TSKSER>
	JRST	TSKIN8		;AND TRY SOME MORE
TSKIP2:
IFE	NTIOM-.IOASC,<		;IN PARANOID MODE?
	MOVE	CHR,TSKIHD+1(B)	;GET INPUT BYTE POINTER
	ILDB	CHR,CHR		;GET FIRST BYTE OF BUFFER
	CAIN	CHR,75		;BUFFER HEADER CHARACTER?
	JRST	TSKIP4		;YES
	BITCH	<% Buffer broken up by TSKSER>
	JRST	-2(J)		;GO PROCESS POTENTIAL DATA BYTE
TSKIP4:	SOS	TSKIHD+2(B)	;DECREMENT COUNT
	IBP	TSKIHD+1(B)	;AND BUMP POINTER
> ;END IFE NTIOM-.IOASC
	JRST	-2(J)		;GO PROCESS REST OF BUFFER
;TSKIEF  --  ROUTINE TO SEE IF ANY DATA BEYOND LOGICAL EOF
;CALL IS:
;
;	PUSHJ	P,TSKIEF
;	RETURN
;
;ROUTINE WILL BITCH IF THERE IS ANY DATA PAST WHERE WE THINK THERE
;SHOULD BE SOME

TSKIEF::STATZ	$TSK,IO.EOF	;ALREADY HAVE EOF?
	POPJ	P,		;YES, THEN DONE
	SETOM	COKFLG(B)	;FLAG EOF IS OK
	PUSHJ	P,TSKINP	;TRY TO READ IN DATA
	CAIA			;CHECK OUT POSSIBLE ERROR
	JRST	TSKIE4		;OOPS - GOT SOMETHING!
	STATZ	$TSK,IO.ERR!IO.EOF	;ANY ERROR BITS?
	POPJ	P,		;YES, I/O ERROR
IFE	NTIOM-.IOASC,<CAME R0,[POINT 6,R1]	;PARTIAL WORD IN PROGRESS?>
TSKIE4:	BITCH	<% Task data past logical EOF>
	POPJ	P,		;OH WELL
;TSKOUT  --  OUTPUT A DATA WORD
;TSKFRC  --  FORCE OUT TO NETWORK ANY DATA SO FAR
;CALL IS:
;
;	MOVX	R1,<DATA-WORD>	;FOR TSKOUT
;	PUSHJ	P,TSKOUT/TSKFRC
;	 ERROR
;	NORMAL

TSKOUT::

IFE	NTIOM-.IOASC,<
	MOVE	R0,[POINT 6,R1]	;BYTE POINTER TO DATA WORD
TSKOU2:	SOSGE	TSKOHD+2(B)	;GOT ANY ROOM LEFT?
	JSP	J,TSKOU8	;NO, GET ANOTHER BUFFER
	AOSN	BLKFLG(B)	;ARE WE STARTING A PROTOCOL BLOCK?
	JRST	TSKOU5		;YES, SPECIAL PREFIX NEEDED
	ILDB	CHR,R0		;GET NEXT DATA BYTE
	IORI	CHR,100		;ENSURE NON-ZERO "ASCII" BYTE
	IDPB	CHR,TSKOHD+1(B)	;STUFF INTO OUTPUT BUFFER
	TLNE	R0,770000	;GOTTEN ENTIRE WORD YET?
	JRST	TSKOU2		;NO, LOOP BACK FOR REST OF WORD
	JRST	.POPJ1##	;DONE

TSKOU5:	MOVEI	CHR,76		;FLAG START OF PROTOCOL BLOCK FOLLOWS
	IDPB	CHR,TSKOHD+1(B)	;STUFF "PREFIX" INTO BUFFER
	JRST	TSKOU2		;NOW GO GET DATA
> ;END OF IFE NTIOM-.IOASC
;STILL TSKOUT::


IFE	NTIOM-.IOIMG,<
TSKOU2:	SOSGE	TSKOHD+2(B)	;ROOM IN OUTPUT BUFFER?
	JSP	J,TSKOU8	;NO, ASK FOR ANOTHER BUFFER
	IDPB	R1,TSKOHD+1(B)	;STUFF IN OUTPUT BUFFER
	JRST	.POPJ1##	;DONE
> ;END IFE NTIOM-.IOIMG

TSKOU8:	OUT	$TSK,		;GET AN EMPTY BUFFER
	JRST	TSKOU9		;VERIFY NEW OUTPUT BUFFER
	STATZ	$TSK,IO.EOF!IO.ERR  ;I/O GOODNESS?
	ERROR	[ASCIZ/Task output error/]

;**********************************************************************
;
;	7.01 LOAD 332 HAS A TENDENCY TO PUT JOBS IN EW STATE AND
;	THEN FORGET ABOUT THEM - SO WE DO NON-BLOCKING I/O
;	AND JUST KEEP TRYING TILL SOMETHING EXCITING HAPPENS
;

	PUSH	P,R1		;NEED A FREE AC
	MOVX	R1,<HB.RIO+^D32>  ;WAIT TWO TICKS OR TILL OUTPUT READY
	HIBER	R1,		;TWIDDLE OUR THUMBS AWHILE
	 BITCH	<% HIBER for output failed>
	POP	P,R1		;RESTORE AAC
	JRST	TSKOU8		;AND TRY ANOTHER OUT

;
;**********************************************************************
TSKOU9:	SKIPLE	TSKOHD+2(B)	;DID WE GET ANYTHING?
	JRST	TSKOP2		;YES, A VALID BUFFER
	BITCH	<% Null buffer foisted on us by TSKSER>
IFE	NTIOM-.IOASC,<MOVEI CHR,^D64*5>  ;ASCII MODE BUFFER SIZE
IFE	NTIOM-.IOIMG,<MOVEI CHR,^D64>  ;IMAGE MODE BUFFER SIZE
	MOVEM	CHR,TSKOHD+2(B)	;WE KNOW WHAT TSKSER SHOULD HAVE DONE . . .
				;THE BYTE POINTER'S ALWAYS BEEN OK . . .
TSKOP2:	IFE	NTIOM-.IOASC,<	;BE PARANOID
	MOVEI	CHR,75		;START OF BUFFER CHARACTER
	IDPB	CHR,TSKOHD+1(B)	;MARK START OF A NEW (FOR US) BUFFER
	SOS	TSKOHD+2(B)	;AND ADJUST BYTE COUNT LEFT
> ;END IFE NTIOM-.IOASC
	JRST	-2(J)		;CONTINUE ABOVE



TSKFRC::

IFE	NTIOM-.IOASC,<
	PUSH	P,R2		;PRESERVE R2
	MOVE	R1,TSKOHD+2(B)	;GET BYTE COUNT
	IDIVI	R1,5		;SEE HOW MANY TRAILING BYTES IN LAST WORD
	MOVN	R1,R2		;(FOR ADDM)
	ADDM	R1,TSKOHD+2(B)	;UPDATE BYTE COUNT (ON G.P.'S)
	POP	P,R2		;RESTORE R2
	SKIPA	CHR,[77]	;GENERATE A FILLER
TSKFR0:	IDPB	CHR,TSKOHD+1(B)	;STUFF INTO OUTPUT BUFFER
	AOJLE	R1,TSKFR0	;FILL OUT REST OF LAST WORD
> ;END IFE NTIOM-.IOASC

	MOVEI	J,TSKFR6+2	;RETURN ADDRESS
	JRST	TSKOU8		;FORCE OUT CURRENT BUFFER
TSKFR6:	JRST	.POPJ1##	;TAKE SUCCESSFUL RETURN
;BITCHM  --  ROUTINE TO BITCH ABOUT NIK-DETECTED TASK I/O BUGS
;CALL IS:
;
;	PUSHJ	P,BITCHM
;	 JFCL	[ASCIZ/TEXT/]
;	RETURN
;
;PRESERVES ALL REGISTERS

BITCHM:	SKIPLE	S.BITC##	;USER WANT ALL THE SAD STORY?
	SKIPLE	S.DETAA##	;YES, FORGET IT IF DETACHED!
	POPJ	P,		;HE DOESN'T CARE OR DETACHED
	EXCH	R1,0(P)		;GET TEXT ADDRESS
	ANDI	R1,-1		;JUST ADDRESS (FOR INDIRECTION)
	OUTSTR	@0(R1)		;BITCH BITCH BITCH
	EXCH	R1,0(P)		;RESTORE R1
	POPJ	P,		;RETURN

	PRGEND
	TITLE	SETRAT	MAKE PROGRAM NAME INTO PERCENTAGE

	SEARCH	TSKUNV,UUOSYM,MACTEN

	SALL

	ENTRY	SETRAI

	TWOSEG	400000

SETRAI::PUSH	P,R0		;SAVE R0
	PUSH	P,R1		;AND R1
	MSTIME	R0,		;READ INITIAL TIME OF DAY
	MOVEM	R0,LKEBLK+.RBTIM(B)  ;PRESET START UP
	MOVE	R0,LKEBLK+.RBSIZ(B)  ;TOTAL FILE SIZE
	ADDI	R0,^D99		;ROUNDING ERRORS
	IDIVI	R0,^D100	;MINIMUM SIZE FOR ONE PERCENT
	MOVEM	R0,LKEBLK+.RBFT1(B)  ;SAVE FOR CHECKING
	SETZM	LKEBLK+.RBMTA(B)  ;FORCE FIRST SETNAM ALWAYS
	POP	P,R1		;RESTORE R1
	POP	P,R0		;AND R0

;FALL INTO INITIAL SETRAT ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

SETRAT::SKIPG	S.PERC##	;IF NOT /PERCENT
	POPJ	P,		;THEN NO NAME CHANGES
	PUSH	P,R0
	PUSH	P,R1
	PUSH	P,R2
	PUSH	P,R4

	MSTIME	R2,		;GET CURRENT TIME
	SUB	R2,LKEBLK+.RBTIM(B)  ;LESS PREVIOUS TIME
	SKIPE	LKEBLK+.RBMTA(B);THIS THE FIRST TIME?
	CAIL	R2,^D15000	;OR A SECOND (OR MORE) PASSED?
	CAIA			;YES TO ONE OF THE ABOVE
	JRST	SETPOP		;NO, JUST GO AWAY

;CALCULATE WORDS PER SECOND TRANSFERRED

	MOVN	R0,P1		;WORDS LEFT TO GO
	ADD	R0,LKEBLK+.RBSIZ(B)  ;R0 := TOTAL WORDS TRANSFERRED
	SUB	R0,LKEBLK+.RBPOS(B)  ;R0 := INCREMENTAL WORDS TRANSFERRED
	CAMGE	R0,LKEBLK+.RBFT1(B)  ;AT LEAST ANOTHER PERCENT?
	SKIPN	LKEBLK+.RBMTA(B);UNLESS FIRST TIME
	CAIA			;NEED TO SET/CHANGE NAME
	 JRST	SETPOP		;DON'T CHANGE NAME YET
	ADDM	R0,LKEBLK+.RBPOS(B)  ;UPDATE TOTAL TRANSFERRED
	ADDM	R2,LKEBLK+.RBTIM(B)  ;UPDATE TO CURRENT TIME
	IMULI	R0,^D1000	;SCALE UP
	IDIV	R0,R2		;WORDS TRANSFERRED PER SECOND
	CAIGE	R0,^D1000	;MORE THAN 3 DIGITS?
	JRST	SETRA2		;NO, USE WORDS PER SECOND
	IDIVI	R0,^D128	;YES, USE BLOCKS PER SECOND INSTEAD
	IDIVI	R0,^D10		;R0:= HIGH DIGIT, R1:= LOW DIGIT
	MOVEI	R2,'B'-'0'	;INDICATE BLOCKS PER SECOND
	JRST	SETRA3		;AND SET RATE ACCORDINGLY
SETRA2:	IDIVI	R0,^D100	;R0:= HIGH ORDER DIGIT
	IDIVI	R1,^D10		;R1:= MIDDLE ORDER DIGIT
SETRA3:	LSH	R2,^D30		;R2:= LOW ORDER DIGIT
	LSHC	R1,^D6		;MAKE
	LSH	R1,^D24		;THREE-DIGIT
	LSHC	R0,^D12		;WORDS PER SECOND
	ADDI	R0,'000'	;MAKE PRINTABLE (AT LEAST SETNAM'ABLE)
	HRR	R4,R0		;AND HANG ONTO IT

;CALCULATE PERCENTAGE OF FILE TRANSFERRED

	MOVE	R0,LKEBLK+.RBPOS(B)	;GET CURRENT POSITION
	IMULI	R0,^D100
	IDIV	R0,LKEBLK+.RBSIZ(B)	;DIVIDE BY TOTAL SIZE
	IDIVI	R0,^D10
	LSH	R1,^D30
	LSHC	R0,-^D24	;RIGHT JUSTIFY
	HRLI	R4,'00%'(R1)	;FIX AND SAV

;NOW SET NEW NAME (IF NEED BE)

	CAME	R4,LKEBLK+.RBMTA(B)	;SAME AS LAST TIME?
	SETNAM	R4,
	MOVEM	R4,LKEBLK+.RBMTA(B)	;SAVE FOR NEXT TIME
	MOVE	R0,LKEBLK+.RBPOS(B)

SETPOP:	POP	P,R4
	POP	P,R2
	POP	P,R1
	POP	P,R0
	POPJ	P,
	END