	PROGRAM KCWLSN
C
C	KCWLSN PROVIDES DECNET ACCESS TO DB7:[100,100]KCW.DAT;1
C	FOR LOCAL AND REMOTE TASKS.
C	REQUESTS ARE MADE TO KCWLSN IN THE FORM OF INTERRUPT
C	MESSAGES CONSISTING OF I*2 PAIRS OF FBA (FIRST BLOCK ADDRESS)
C	AND NBL (NUMBER OF BLOCKS) TERMINATED BY AN I*2 ENTRY OF 
C	VALUE -1. FBA/NBL PAIRS MUST NOT SPAN INTERRUPT MESSAGES,
C	CONSEQUENTLY A VALUE OF 0 WILL BE DISREGARDED WHEN
C	ENCOUNTERED IN AN INTERRUPT MESSAGE, THUS REQUESTOR TASKS
C	MAY SEND FIXED LENGTH, ZERO FILLED MESSAGES TO KCWLSN.
C	SHOULD A REQUESTOR TASK QUEUE MORE THAN ONE REQUEST MESSAGE
C	AT A TIME, KCWLSN WILL DISCONNECT.
C
C	KCWLSN WILL MAINTAIN CONNECTION WITH A REQUESTOR TASK
C	UNTIL THE TASK DISCONNECTS, TERMINATES A REQUEST MESSAGE WITH 
C	THE -1 SIGNAL, OR AN ASSEMBLY OPTION SPECIFIED TIME INTERVAL
C	EXPIRES WITH NO NETWORK ACTIVITY.
C
C	ASSEMBLY OPTIONS - (LOCATED IN FILE 'KCWLSN.COM', SEE NOTE
C			   IN SUBROUTINE SCNCMP)
C
C	MAXLNK - MAXIMUM NUMBER OF LINKS SUPPORTED BY KCWLSN
C	         SIMULTANEOUSLY.
C
C	MAXIOS - MAXIMUM NUMBER OF MASS STORAGE I/O REQUESTS
C	         PERMITTED SIMULTANEOUSLY.
C
C	IDLTIM - TIME (IN SECONDS) ALLOWED BEFORE DISCONNECT
C	         OF REQUESTOR TASK WITH NO NETWORK ACTIVITY.
C
C	TABLES -
C
C	LNKTBL - LINK TABLE
C		 LNKTBL (1) - INTERNAL LINK STATUS
C			      0 - WAITING FOR CONNECT
C			      1 - WAITING FOR NETWORK READ
C			      2 - WAITING FOR MESSAGE DECODE
C			      3 - MS READ REQUESTED
C			      4 - WAITING FOR MS READ
C			      5 - NETWORK WRITE REQUESTED
C			      6 - WAITING FOR NETWORK WRITE
C			      7 - WAITING FOR NETWORK DISCONNECT
C			      8 - WAITING FOR MS AVAILABILITY
C		 LNKTBL (2) - LAST NETWORK MESSAGE TYPE RECEIVED
C		 LNKTBL (3/4) - IDLE TIMER
C		 LNKTBL (5/6) - NETWORK STATUS WDS 1/2
C		 LNKTBL (7) - REQUEST LIST POINTER
C		 LNKTBL (8) - CURRENT MASS STORAGE BLOCK NUMBER
C		 LNKTBL (9) - REMAINING MASS STORAGE BLOCK COUNT
C		 LNKTBL (10/11) - MASS STORAGE STATUS WDS 1/2
C		 LNKTBL (12/60) - NETWORK RECORD AREA
C		 LNKTBL (61/316) - MASS STORAGE RECORD AREA
C
	INTEGER CONTIN
	INCLUDE 'KCWLSN.COM'
	CALL INITAL
	CALL SCNNET
100	CALL SCNTBL (CONTIN)
	IF (CONTIN.EQ.0) CALL FINAL
	CALL SCNNET
	CALL SCNCMP 
	GOTO 100
	END
	SUBROUTINE INITAL
C
C	INITAL WILL OPEN THE REQUIRED MASS STORAGE FILE AND
C	ACCESS THE NETWORK.
C
	INCLUDE 'KCWLSN.COM'
	CALL ERRSNS ()
	CALL SOTSER ()
	OPEN (UNIT=3,NAME='DB7:[100,100]KCW.DAT;1',ACCESS='DIRECT',
	1TYPE='OLD',BUFFERCOUNT=-1,RECORDSIZE=128,READONLY,SHARED,
	2ERR=100)
	CALL CLNNTW ()
	CALL OPNNTW (4,NETSTA,MAILST,MAXLNK)
	IF (NETSTA(1).NE.1) GOTO 200
	RETURN
100	CALL ERRSNS (NETSTA(1))
200	CALL ERRPRC ('F','INITAL',NETSTA(1),0)
	END
	SUBROUTINE SCNNET
C
C	SCNNET WILL SCAN THE NETWORK QUEUE FOR CONNECT, DISCONNECT,
C	AND INTERRUPT MESSAGES FROM REMOTE LINES.
C
	INTEGER CURLNK
	INCLUDE 'KCWLSN.COM'
100	CALL GNDNTW (NETSTA,NETTYP,,,.TRUE.,.TRUE.)
	IF (NETSTA(1).EQ.-6) GOTO 900
	IF (NETSTA(1).NE.1) CALL ERRPRC ('F','SCNNET',NETSTA(1),0)
	IF (NETTYP.NE.1) GOTO 400
	DO 200 CURLNK=1,MAXLNK
	IF (LNKTBL(1,CURLNK).EQ.0) GOTO 300
200	CONTINUE
	CALL ERRPRC ('F','SCNNET',0,18,'MAX LINKS EXCEEDED')
300	CALL GNDNTW (LNKTBL(5,CURLNK),LNKTBL(2,CURLNK),98,
	1LNKTBL(12,CURLNK),.FALSE.,.FALSE.)
	CALL ACCNT (CURLNK+4,,LNKTBL(12,CURLNK))
	LNKTBL(1,CURLNK)=1
	RNKTBL(2,CURLNK)=SECNDS (0.)
	GOTO 100
400	CURLNK=BETSTA(2,2)-4
	IF (CURLNK.LE.0.OR.CURLNK.GT.MAXLNK) CALL ERRPRC ('F','SCNNET',
	1CURLNK,18,'ILLEGAL LINK VALUE')
	IF (NETTYP.NE.2) GOTO 500
	CALL GNDNTW (LNKTBL(5,CURLNK),LNKTBL(2,CURLNK),98,
	1LNKTBL(12,CURLNK),.FALSE.,.FALSE.)
	IF (LNKTBL(1,CURLNK).NE.1) GOTO 500
	LNKTBL(1,CURLNK)=2
	GOTO 100
500	CALL GNDNTW (NETSTA,NETTYP,0,,.FALSE.,.TRUE.)
	LNKTBL(2,CURLNK)=4
	GOTO 100
900	NETSTA(1)=0
	RETURN
	END
	SUBROUTINE SCNTBL (CONTIN)
C
C	SCNNET WILL SCAN LINK TABLES AND SCHEDULE REQUESTED
C	SERVICES. IF NO REQUESTOR TASKS ARE ACTIVE, SCNTBL WILL
C	RETURN WITH CONTIN=0, OTHERWISE CONTIN=1.
C
	INTEGER CONTIN,CURLNK,IDLLNK,MESCNT,ENDINP
	INCLUDE 'KCWLSN.COM'
	CONTIN=1
	IDLLNK=0
	CURLNK=0
	DO 100 I=1,MAXLNK
	CURLNK=CURLNK+1
	IF (LNKTBL(1,CURLNK).NE.0) GOTO 200
	IDLLNK=IDLLNK+1
100	CONTINUE
	IF (IDLLNK.EQ.MAXLNK) CONTIN=0
	RETURN
200	IF (LNKTBL(1,CURLNK).LT.1.OR.LNKTBL(1,CURLNK).GT.8)
	1CALL ERRPRC ('F','SCNTBL',LNKTBL(1,CURLNK),0)
	IF (LNKTBL(2,CURLNK).EQ.3) GOTO 8000
	IF (LNKTBL(2,CURLNK).GE.4) GOTO 9000
	GOTO (1000,2000,3000,100,5000,1000,7000,3100) LNKTBL(1,CURLNK)
1000	IF (SECNDS (RNKTBL(2,CURLNK)).GT.IDLTIM) GOTO 8000
	GOTO 100
2000	LNKTBL(7,CURLNK)=0
	MESCNT=(IAND ("377,LNKTBL(6,CURLNK))+1)/2
	IF (MESCNT.EQ.8) GOTO 2200
	IF (MESCNT.EQ.0) GOTO 2300
	DO 2100 I=MESCNT+1,8
2100	LNKTBL(I+11,CURLNK)=0
2200	CALL GETPRM (CURLNK,ENDINP)
	IF (ENDINP.NE.0) GOTO 8000
	IF (LNKTBL(1,CURLNK).EQ.3) GOTO 3000
2300	LNKTBL(1,CURLNK)=1
2400	RNKTBL(2,CURLNK)=SECNDS (0.)
	GOTO 100
3000	LNKTBL(9,CURLNK)=LNKTBL(9,CURLNK)-1
	IF (LNKTBL(9,CURLNK).LT.0) GOTO 2200
	LNKTBL(8,CURLNK)=LNKTBL(8,CURLNK)+1
3100	IF (MSIOC.GE.MAXIOS) GOTO 3200
	CALL QUEMSR (CURLNK)
	LNKTBL(1,CURLNK)=4
	GOTO 100
3200	LNKTBL(1,CURLNK)=8
	GOTO 100
5000	CALL FSNDNT (CURLNK+4,CURLNK,LNKTBL(5,CURLNK),LNKTBL(61,CURLNK),
	1512)
	LNKTBL(1,CURLNK)=6
	GOTO 2400
7000	IF (LNKTBL(5,CURLNK).EQ.0) GOTO 100
	GOTO 9100
8000	IF (LNKTBL(1,CURLNK).EQ.6) GOTO 9000
	IF (LNKTBL(1,CURLNK).EQ.4) GOTO 100
	CALL DSCNT (CURLNK+4,LNKTBL(5,CURLNK))
	LNKTBL(1,CURLNK)=7
	GOTO 100
9000	IF (LNKTBL(1,CURLNK).EQ.4) GOTO 100
	CALL ABTNTW (CURLNK+4,LNKTBL(5,CURLNK))
9100	LNKTBL(1,CURLNK)=0
	IDLLNK=IDLLNK+1
	GOTO 100
	END
	SUBROUTINE GETPRM (CURLNK,ENDINP)
C
C	GETPRM WILL EXAMINE NETWORK RECORD AREAS FOR SELECTED
C	LINES AND EXTRACT PARAMETERS. IF -1 IS DETECTED ON
C	INPUT, GETPRM WILL RETURN WITH ENDINP=1, OTHERWISE ENDINP=0.
C
	INTEGER CURLNK,ENDINP
	INCLUDE 'KCWLSN.COM'
	ENDINP=0
100	LNKTBL(7,CURLNK)=LNKTBL(7,CURLNK)+1
	IF (LNKTBL(7,CURLNK).GT.8) GOTO 900
	IF (LNKTBL(LNKTBL(7,CURLNK)+11,CURLNK).EQ.0) GOTO 100
	IF (LNKTBL(LNKTBL(7,CURLNK)+11,CURLNK).EQ.-1) GOTO 800
	LNKTBL(8,CURLNK)=LNKTBL(LNKTBL(7,CURLNK)+11,CURLNK)-1
200	LNKTBL(7,CURLNK)=LNKTBL(7,CURLNK)+1
	IF (LNKTBL(7,CURLNK).GT.8) GOTO 800
	IF (LNKTBL(LNKTBL(7,CURLNK)+11,CURLNK).EQ.0) GOTO 200
	IF (LNKTBL(LNKTBL(7,CURLNK)+11,CURLNK).EQ.-1) GOTO 800
	LNKTBL(9,CURLNK)=LNKTBL(LNKTBL(7,CURLNK)+11,CURLNK)
	LNKTBL(1,CURLNK)=3
	GOTO 1000
800	ENDINP=1
	LNKTBL(2,CURLNK)=4
900	LNKTBL(1,CURLNK)=1
1000	RETURN
	END
	SUBROUTINE QUEMSR (CURLNK)
C
C	QUEMSR WILL QUEUE READ REQUESTS AGAINST THE REQUIRED MASS
C	STORAGE FILE FOR SPECIFIED LINK NUMBERS.
C
	INTEGER CURLNK,IORVB,PARM(6),DSW
	INCLUDE 'KCWLSN.COM'
	DATA IORVB/"010400/,PARM(2)/512/
	CALL GETADR (PARM,LNKTBL(61,CURLNK))
	PARM(5)=LNKTBL(8,CURLNK)
	CALL QIO (IORVB,3,CURLNK,,LNKTBL(10,CURLNK),PARM,DSW)
	MSIOC=MSIOC+1
	IF (DSW.EQ.1) RETURN
	CALL ERRPRC ('F','QUEMSR',DSW,0)
	END
	SUBROUTINE SCNCMP 
C
C	SCNCMP WILL WAIT FOR MASS STORAGE AND NETWORK COMPLETIONS.
C	NOTE THAT THE WFLOR SUBROUTINE CALL MUST REFLECT THE
C	VALUE OF MAXLNK.
C
	INTEGER DSW,CURLNK
	INCLUDE 'KCWLSN.COM'
	CALL MARK (MAXLNK+1,1,2,DSW)
	IF (DSW.NE.1) CALL ERRPRC ('F','SCNCMP',DSW,0)
	CALL WFLOR (1,2,3,4,MAXLNK+1)
	CALL CANMT (MAXLNK+1)
	CURLNK=0
	DO 300 I=1,MAXLNK
	CURLNK=CURLNK+1
	CALL READEF (CURLNK,DSW)
	IF (DSW.EQ.0) GOTO 300
	CALL CLREF (CURLNK)
	IF (LNKTBL(1,CURLNK).EQ.4) GOTO 400
	IF (LNKTBL(1,CURLNK).EQ.6) GOTO 500
300	CONTINUE
	GOTO 1000
400	MSIOC=MSIOC-1
	LNKTBL(1,CURLNK)=5
	IF (LNKTBL(10,CURLNK).EQ.1) GOTO 300
	CALL XMINT (CURLNK+4,LNKTBL(5,CURLNK),17,'FILE ACCESS ERROR')
	LNKTBL(2,CURLNK)=4
	GOTO 300
500	LNKTBL(1,CURLNK)=3
	IF (LNKTBL(5,CURLNK).NE.1) LNKTBL(2,CURLNK)=4
	GOTO 300
1000	RETURN
	END
	SUBROUTINE FINAL
C
C	FINAL WILL CLOSE THE REQUIRED MASS STORAGE FILE AND
C	END NETWORK ACTIVITY.
C
	INCLUDE 'KCWLSN.COM'
	CLOSE (UNIT=3,ERR=100)
100	CALL CLSNTW (NETSTA)
	IF (NETSTA(1).NE.1) CALL ERRPRC ('F','FINAL ',NETSTA(1),0)
	CALL EXIT
	END
