2!		PROGRAM		: DIALER.BAS
5!		VERSION		: V10.1
6!		EDIT		: G
7!		EDIT DATE	: 01-NOV-91
10	EXTEND
11!	&
	&
	&
	!		C O P Y R I G H T &
	&
	&
  !		      Copyright (C) 1978, 1991 by &
  !	        Digital Equipment Corporation, Maynard, Mass. &
  !	&
  !	&
  !	This software is furnished under a license and may be used and &
  !	copied  only  in accordance with the terms of such license and &
  !	with the  inclusion  of  the  above  copyright  notice.   This &
  !	software  or  any  other copies thereof may not be provided or &
  !	otherwise made available to any other person.  No title to and &
  !	ownership of the software is hereby transferred. &
  !	&
  !	The information in this software is subject to change  without &
  !	notice  and should not be construed as a commitment by Digital &
  !	Equipment Corporation. &
  !	&
  !	DIGITAL assumes no responsibility for the use  or  reliability &
  !	of its software on equipment that is not supplied by DIGITAL. &
  !	&
  !******************************************************************* &

20	! &
	&
	&
	!	M O D I F I C A T I O N    H I S T O R Y &
	&
	&

21	! VER/ED	EDIT DATE	REASON &
	! &

100	! &
	&
	&
	!	G E N E R A L    D E S C R I P T I O N &
	&
	&

300	! &
	&
	&
	!	I / O    C H A N N E L S &
	&
	&

301	!	CHANNEL #	USED FOR &
	&
	!	0		TERMINAL OUTPUT &
	!	1		COMMAND INPUT/OUTPUT &
	!	2		STATION DATA FILE &
	!	3		PORT DATA FILE &
	!	4		OUTPUT LOG FILE &
	!	6		REMOTE KEYBOARD &
	!	9		DIALER I/O &

800	! &
	&
	&
	!	F U N C T I O N / S U B R O U T I N E    D E S C . &
	&
	&

801!	FUNCTION/SUBROUTINE		USE &
   !	&

900	! &
	&
	&
	!	D I M E N S I O N    S T A T E M E N T S &

910	DIM m%(30%),TELCO%(32%) &
		! m%		general sys call array &
		! TELCO%	telephone string conversion &

920	DIM #2%,STATION.NAME$(255%)	  =10%, &
		STATION.TELCO1$(255%)	  =24%, &
		STATION.TELCO2$(255%)	  =24%, &
		STATION.CLASS$(255%)	  =6%, &
		STATION.ACTION$(255%)	  =6%, &
		STATION.DESCRIPTION$(255%)=28% &
		! station definition (virtual) array &

930	DIM #3%,PORT.NAME$(63%)		  =10%, &
		PORT.ID$(63%)		  =24%, &
		PORT.CLASS$(63%)	  =6%, &
		PORT.DEVICE$(63%)	  =6%, &
		PORT.ACTION$(63%)	  =6%, &
		PORT.DESCRIPTION$(63%)	  =20% &
		! port definition (virtual) array &
	&

999	! &
	&
	!	M A I N    C O D I N G    A R E A &
	&

1000	ON ERROR GOTO 19000 &
	\ PRINT IF CCPOS(0%) &
		! SET UP STANDARD ERROR TRAP. &
		! RETURN KB: TO LEFT MARGIN. &

1010	I$="V10.1-G" &
		! SET UP VERSION/EDIT NUMBER. &

1020	S$=SYS(CHR$(6%)+CHR$(9%)) &
	\ KB0%=CVT$%(MID(S$,1%,2%)) &
	\ JOB%=(SWAP%(KB0%) AND 255%)/2% &
	\ KB0%=(KB0% AND 255%)/2% &
	\ PRINT "DIALER"+CHR$(9%)+I$+CHR$(9%)+CVT$$(RIGHT(S$,3%),4%) UNLESS E0% &
		! PRINT PROGRAM/SYSTEM HEADER. &

1030	GOSUB 10010 &
		! GET PACKAGE DEVICE AND PPN &

1500	! &
	&
	&
	!	I N I T I A L I Z A T I O N   C O D E &

1510	GOSUB 10100 &
	\ GOSUB 1520 &
	\ GOTO 2000 &
		! DEFINE TEXT FOR MESSAGES &
		! INITIALIZE STATION AND PORT FILES &
		! JOIN MAINLINE CODE &

1520	PORT.FILE$=DEVICE.PPN$+"DIALP.DAT" &
	\ PORT.FILE.SIZE%=16% &
	\ Z%=FND%(PORT.MSG$+FILE.MSG$+INIT.MSG$) &
		IF FNINIT%(PORT.FILE$,PORT.FILE.SIZE%) &
	\ GOTO 32700 IF E% &
		! INITIALIZE PORT DATA FILE IF NECESSARY &
		! EXIT ON ERROR &

1530	STATION.FILE$=DEVICE.PPN$+"DIALS.DAT" &
	\ STATION.FILE.SIZE%=64% &
	\ Z%=FND%(STATION.MSG$+FILE.MSG$+INIT.MSG$) &
		IF FNINIT%(STATION.FILE$,STATION.FILE.SIZE%) &
	\ GOTO 32700 IF E% &
		! INITIALIZE STATION DATA FILE IF NECESSARY &
		! EXIT ON ERROR &

1540	RETURN &
		! ALL DONE
1999!	&

2000	! &
	&
	&
	!	G E T   C O M M A N D   L I N E &

2010	GOTO 32700 IF detached% &
	\ e%,callback%=0% &
	\ E$=NULL$ &
	\ OPEN "_KB:DIALER.CMD" AS FILE 1% &
	\ logf%=1% &
	\ GOTO 2015 IF E0% &
	\ CMD$=NULL$ &
	\ PRINT #1% &
	\ PRINT #1%, "DIAL> "; &
	\ INPUT LINE #1%, C0$ &
	\ CMD$=CMD$+C0$ &

2015	CMD$=CVT$$(CMD$,508%)		!256%+128%+64%+32%+16%+8%+4% &
	\ GOTO 2000 UNLESS LEN(CMD$) &
	\ PRINT #1% &
	\ i%=INSTR(1%,cmd$,"/PRI") &
	\ GOTO 2020 UNLESS i% &
	\ j%=INSTR(i%,cmd$+" "," ") &
	\ k%=INSTR(i%,cmd$,"=") &
	\ k%=j%-1% UNLESS k% &
	\ device.ppn$=MID(cmd$,k%+1%,j%-k%-1%) &
	\ cmd$=CVT$$(LEFT(cmd$,i%-1%)+RIGHT(cmd$,j%),8%) &
	\ GOSUB 1530 &
		! IF user wants to use a private data base, let him. &

2020	GOTO 2080 UNLESS FNGETKWD% &
	\ GOTO 32700 IF FNKWD2%("EXIT") &
	\ GOTO 3000  IF FNKWD2%("DIAL") &
	\ GOTO 2110  IF FNKWD2%("DEFINE") &
	\ GOTO 2120  IF FNKWD2%("LIST") &
	\ GOTO 2130  IF FNKWD2%("PURGE") &
	\ GOTO 2140  IF FNKWD2%("CALLBACK") &
	\ GOTO 2150  IF FNKWD2%("CONNECT") &
	\ GOTO 2030  IF FNKWD2%("HELP") &
	\ CMD$=KWD$+CMD$ &
	\ KWD$="DIAL" &
	\ GOTO 3000 &
		! DISPATCH ON INITIAL KEYWORD &
		! ASSUME "DIAL" IF NO KEYWORD MATCH &

2030	Z%=FND%("Valid commands are:") &
	\ Z%=FND%(" DEFINE   - Enter STATION or PORT entry") &
	\ Z%=FND%(" PURGE    - Delete STATION or PORT entry") &
	\ Z%=FND%(" LIST     - List STATION or PORT tables") &
	\ Z%=FND%(" DIAL     - Dial a STATION on a PORT") &
	\ Z%=FND%(" CALLBACK - Dial STATION on current PORT") &
	\ Z%=FND%(" CONNECT  - Connect to a STATION on a PORT") &
	\ Z%=FND%(" EXIT     - Leave program") &
	\ Z%=FND%(" HELP     - Print this text") &
	\ GOTO 2010 &

2080	Z%=FND%(ERR.SYNTAX$+"'"+CMD$+"'") &
	\ GOTO 9000 IF E0% &
	\ GOTO 2000 &
		! EXIT IF CCL ENTRY &
		! ELSE TRY FOR NEW COMMAND &

2100	! &
	&
	!	SECONDARY KEYWORD PROCESSING &
	!	DEFINE, LIST, AND PURGE COMMANDS &

2110	CMD%=1% \ Z$="Define" \ GOTO 2200 	! DEFINE COMMAND
2120	CMD%=2% \ Z$="List"   \ GOTO 2200 	! LIST   COMMAND
2130	CMD%=3% \ Z$="Purge"  \ GOTO 2200 	! PURGE  COMMAND
2140	KWD$="DIAL" \ callback%=-1% \ GOTO 3000 ! CALLBACK COMMAND
2150	KWD$="DIAL" \ connect%=-1% \ GOTO 3000 	! CONNECT COMMAND &

2200	GOTO 2300 IF FNGETKWD% &
	\ PRINT #1%, Z$;" STATION or PORT ? "; &
	\ INPUT LINE #1%,KWD$ &
	\ KWD$=CVT$$(KWD$,252%) &

2300	GOTO 5000 IF FNKWD3%("STATIONS") &
	\ GOTO 6000 IF FNKWD3%("PORTS") &
	\ MSG$=Z$+QUAL.MSG$ &
	\ GOTO 9000 &

3000	! &
	&
	!	HANDLE DIAL COMMANDS &

3010	MSG$=ERR.SYNTAX$ &
	\ GOTO 9000 UNLESS FNGETKWD% &
	\ GOTO 3030 IF FNQUOTES% &
		! SYNTAX ERROR IF NOTHING IN COMMAND LINE &
		! ASSUME TELEPHONE NUMBER IF QUOTED STRING &
		! FALL THROUGH FOR SYMBOLIC STATION NAMES &

3020	STATION$=KWD$ &
	\ CMD%=1% &
	\ OPEN STATION.FILE$ FOR INPUT AS FILE 2%, MODE 8192% &
	\ GOSUB 5800 &
	\ GOTO 9000 IF E% &
	\ GOSUB 5910 &
	\ CLOSE 2% &
	\ TELCO$=TELCO2$ &
	\ E%=0% &
	\ GOSUB 11100 IF LEN(TELCO$) &
	\ GOTO 9000 IF E% &
	\ TELCO2$=TELCO$ &
	\ TELCO$=TELCO1$ &
	\ GOTO 3040 &
		! SET STATION NAME EQUAL TO KEYWORD &
		! COMMAND TYPE IS 1, 2, OR 3 &
		! LOOKUP STATION IN STATION FILE &
		! EXIT IF STATION IS NOT DEFINED &
		! GET ALL STATION RELATED INFO &
		! SETUP AND VERIFY TELCO2$ FOR DUAL DIAL CALLS &
		! AND SETUP TELCO1$ BELOW &

3030	STATION$=KWD$ &
	\ CMD%=4% &
	\ TELCO$=KWD$ &
		! SET STATION TO BE TELEPHONE NUMBER &
		! COMMAND TYPE IS 4, 5, OR 6 &
		! TELEPHONE NUMBER IS LITERAL &

3040	GOSUB 11100 &
	\ GOTO 9000 IF E% &
	\ TELCO1$=TELCO$ &
	\ GOTO 3100 &
		! CHECK SYNTAX OF TELEPHONE NUMBER AND SQUASH &
		! EXIT IF BAD TELEPHONE NUMBER &
		! GO PROCESS PORT PORTION OF DIAL COMMAND &

3100	! &
	&
	!	PROCESS PORT PORTION OF "DIAL" COMMAND &

3120	GOTO 3180 UNLESS FNGETKWD% &
	\ GOTO 3120 IF FNKWD%("ON",2%) &
	\ GOTO 3120 IF FNKWD3%("USING") &
	\ GOTO 3120 IF FNKWD3%("PORT") &
	\ GOTO 3150 IF FNQUOTES% &
		! GET NEXT KEYWORD &
		! TOSS ANY NOISE WORDS &
		! ASSUME LITERAL DIALER ID IF QUOTED STRING &
		! FALL THROUGH FOR SYMBOLIC PORT NAMES &

3140	PORT$=KWD$ &
	\ CMD%=CMD%+1% &
	\ OPEN PORT.FILE$ FOR INPUT AS FILE 3%, MODE 8192% &
	\ GOSUB 6800 &
	\ GOTO 9000 IF E% &
	\ GOSUB 6910 &
	\ CLOSE 3% &
	\ GOTO 3160 &
		! WE HAVE A SYMBOLIC PORT NAME &
		! COMMAND TYPE IS 2 OR 5 &
		! LOOKUP PORT INFO IN PORT FILE &
		! EXIT IF PORT NOT FOUND &
		! GET ALL PORT RELATED INFO &

3150	PORT$=KWD$ &
	\ CMD%=CMD%+2% &
	\ ID$=KWD$ &
		! WE HAVE A LITERAL DIALER ID &
		! COMMAND TYPE IS 3 OR 6 &

3160	GOSUB 14100 &
	\ GOTO 9000 IF E% &
		! VERIFY DIALER ID FOR CORRECT SYNTAX &
		! EXIT ON BAD DIALER ID &
		! PROCEED WITH COMMAND PROCESSING &

3180	MSG$=ERR.SYNTAX$ &
	\ ON CMD% GOTO 3200,3900,3800,9000,3800,3800 &
		! DISPATCH ON COMMAND TYPE &

3200	! &
	&
	!	DIAL station-name			COMMAND TYPE = 1 &
	&
	!	SEARCH FOR PORT CLASS MATCHING STATION CLASS &
	!	EXECUTE ACTION ROUTINE &

3210	CURRENT.PNDX%=1% &
	\ MATCH%=0% &

3220	TMR%=0% &

3230	ON ERROR GOTO 3290 &
	\ OPEN PORT.FILE$ FOR INPUT AS FILE 3%, MODE 8192% &
	\ ON ERROR GOTO 19000 &

3240	FOR PNDX%=CURRENT.PNDX% TO 63% &
	\ flag% = port.class$(pndx%)=s.class$ &
	\ flag% = flag% AND (port.device$(pndx%)="KB"+NUM1$(kb0%)) &
		  IF callback%=-1% &
	\ GOTO 3250 IF flag% &
	\ NEXT PNDX% &
	\ CLOSE 3% &
	\ MSG$=STATION.MSG$+STATION$+" Requires Port Class "+S.CLASS$+ &
	       " - No Matching Port Defined" &
	\ MSG$="Call Failed on all "+S.CLASS$+" Ports" IF MATCH% &
	\ GOTO 9000 UNLESS callback%=-1% &
	\ callback%=1% &
	\ GOTO 3210 &
	! try to get the same line IF callback specified &
	! IF that fails, try all ports &

3250	GOSUB 6900 &
	\ CLOSE 3% &
	\ MATCH%=-1% &
	\ Z%=FND%("Dialing Station "+STATION$+" on Port "+PORT$) &
	\ GOSUB 14100 &
	\ GOTO 3260 UNLESS e% &
	\ Z%=FND%(MSG$) &
	\ GOTO 3220 &

3260	GOSUB 7000 &
	\ GOTO 9100 UNLESS e% &
	\ Z%=FND%(MSG$) &
	\ CURRENT.PNDX%=PNDX%+1% &
	\ GOTO 3220 &

3290	CLOSE 3% &
	\ Z%=FND%(WAIT.MSG$+PORT.MSG$+FILE.MSG$) IF TMR%=4% &
	\ SLEEP 2% &
	\ TMR%=TMR%+2% &
	\ RESUME 3230 &

3800	! &
	&
	!	DIAL station-name ON "dialer-id"	COMMAND TYPE = 3 &
	!	DIAL "telephone-number" ON port-name	COMMAND TYPE = 5 &
	!	DIAL "telephone-number" ON "dialer-id"	COMMAND TYPE = 6 &
	&
	!	NO SEARCH FOR PORT IS REQUIRED &
	!	DEFAULT ACTION ROUTINE IS EXECUTED &

3810	ACTION$="NONE" &

3900	! &
	&
	!	DIAL station-name ON port-name		COMMAND TYPE = 2 &
	&
	!	NO SEARCH FOR PORT IS REQUIRED &
	!	ACTION ROUTINE DEFINED FOR STATION IS EXECUTED &

3910	GOSUB 7000 &
	\ GOTO 9100 &
		! EXECUTE ACTION ROUTINE &
		! EXIT WITH OR WITHOUT ERROR &

5000	! &
	&
	!	HANDLE STATION COMMANDS &

5010	GOTO 5020 IF FNGETKWD% &
	\ STATION$=NULL$ &
	\ GOTO 5030 IF CMD%=2% &
	\ PRINT #1% &
	\ PRINT #1%, STATION.NAME.MSG$;"? "; &
	\ INPUT LINE #1%, STATION$ &
	\ STATION$=CVT$$(STATION$,252%) &
	\ GOTO 5030 &

5020	STATION$=KWD$ &
	\ Z%=FND%(STATION.NAME.MSG$+fnprmpt$(STATION$)) IF CMD%=1% &

5030	ON CMD% GOTO 5100,5400,5600 &
		! DISPATCH TO DEFINE STATION, &
		!	      LIST   STATION, &
		!	   OR PURGE  STATION &

5100	! &
	&
	!	DEFINE STATION &

5110	CHANGE.FLAG%=0% &
	\ OPEN STATION.FILE$ FOR INPUT AS FILE 2%, MODE 8192% &
	\ TELCO1$=NULL$ &
	\ TELCO2$=NULL$ &
	\ S.CLASS$=NULL$ &
	\ S.ACTION$="NONE" &
	\ S.DESCRIPTION$=NULL$ &
	\ GOSUB 5800 &
	\ GOSUB 5910 UNLESS e% &
		! OPEN STATION FILE READ ONLY &
		! GET CURRENT STATION INFO IF ALREADY DEFINED &
		! INSURE THERE IS A FREE SLOT FOR NEW DEFINITION &

5130	CLOSE 2% &
	\ MSG$=NO.SPACE$ &
	\ GOTO 9000 UNLESS FREE% &
	\ PRINT #1%, STATION.TELCO1.MSG$;fnprmpt$(TELCO1$); &
	\ INPUT LINE #1%, NEW.TELCO1$ &
	\ NEW.TELCO1$=CVT$$(NEW.TELCO1$,252%) &
	\ GOTO 5130 UNLESS LEN(TELCO1$)+LEN(NEW.TELCO1$) &
	\ GOTO 5150 UNLESS LEN(NEW.TELCO1$) &
	\ TELCO$=NEW.TELCO1$ &
	\ GOSUB 11100 &
	\ GOTO 5140 UNLESS e% &
	\ Z%=FND%(MSG$) &
	\ GOTO 5130 &
		! EXIT IF NO SLOTS AVAILABLE FOR NEW STATION ENTRY &
		! PROMPT FOR XMIT TELEPHONE NUMBER &
		! VERIFY TELEPHONE NUMBER FOR CORRECT SYNTAX &
		! REPROMPT IF ILLEGAL. SET CHANGE FLAG IF OKAY. &

5140	TELCO1$=NEW.TELCO1$ &
	\ CHANGE.FLAG%=-1% &

5150	PRINT #1%, STATION.TELCO2.MSG$;fnprmpt$(TELCO2$); &
	\ INPUT LINE #1%, NEW.TELCO2$ &
	\ NEW.TELCO2$=CVT$$(NEW.TELCO2$,252%) &
	\ GOTO 5170 UNLESS LEN(NEW.TELCO2$) &
	\ TELCO$=NEW.TELCO2$ &
	\ GOSUB 11100 &
	\ GOTO 5160 UNLESS e% &
	\ Z%=FND%(MSG$) &
	\ GOTO 5150 &
		! PROMPT FOR RECV TELEPHONE NUMBER &
		! VERIFY TELEPHONE NUMBER FOR CORRECT SYNTAX &
		! REPROMPT IF ILLEGAL. SET CHANGE FLAG IF OKAY. &

5160	TELCO2$=NEW.TELCO2$ &
	\ CHANGE.FLAG%=-1% &

5170	PRINT #1%, STATION.CLASS.MSG$;fnprmpt$(S.CLASS$); &
	\ INPUT LINE #1%, NEW.CLASS$ &
	\ NEW.CLASS$=CVT$$(NEW.CLASS$,252%) &
	\ GOTO 5170 UNLESS LEN(S.CLASS$)+LEN(NEW.CLASS$) &
	\ GOTO 5200 UNLESS LEN(NEW.CLASS$) &
	\ S.CLASS$=NEW.CLASS$ &
	\ CHANGE.FLAG%=-1% &
		! PROMPT FOR STATION CLASS &
		! REPROMPT IF ILLEGAL. SET CHANGE FLAG IF OKAY. &

5200	PRINT #1%, STATION.ACTION.MSG$;fnprmpt$(S.ACTION$); &
	\ INPUT LINE #1%, NEW.ACTION$ &
	\ NEW.ACTION$=CVT$$(NEW.ACTION$,252%) &
	\ GOTO 5200 UNLESS LEN(S.ACTION$)+LEN(NEW.ACTION$) &
	\ GOTO 5210 UNLESS LEN(NEW.ACTION$) &
	\ S.ACTION$=NEW.ACTION$ &
	\ CHANGE.FLAG%=-1% &
		! PROMPT FOR ACTION ROUTINE &
		! REPROMPT IF ILLEGAL. SET CHANGE FLAG IF OKAY. &

5210	PRINT #1%, STATION.DESCRIPTION.MSG$;fnprmpt$(S.DESCRIPTION$); &
	\ INPUT LINE #1%, NEW.DESCRIPTION$ &
	\ NEW.DESCRIPTION$=CVT$$(NEW.DESCRIPTION$,20%)		!4%+16% &
	\ GOTO 5220 UNLESS LEN(NEW.DESCRIPTION$) &
	\ S.DESCRIPTION$=CVT$$(NEW.DESCRIPTION$,156%) &
	\ CHANGE.FLAG%=-1% &
		! PROMPT FOR DESCRIPTION ROUTINE &
		! REPROMPT IF ILLEGAL. SET CHANGE FLAG IF OKAY. &

5220	GOTO 5300 &
		! NEW STATION QUERIES GO HERE &

5300	MSG$=STATION.MSG$+STATION$+NO.CHANGE$ &
	\ GOTO 9100 UNLESS CHANGE.FLAG% &
	\ TMR%=0% &
		! DISPLAY MESSAGE AND EXIT IF NO CHANGE TO STATION DATA &

5310	OPEN STATION.FILE$ AS FILE 2% &
	\ GOTO 5390 IF STATUS AND 1024% &
	\ GOSUB 5800 &
	\ MSG$=NO.SPACE$ &
	\ GOTO 9000 UNLESS FREE% &
	\ STATION.NAME$(FREE%)=STATION$ &
	\ STATION.TELCO1$(FREE%)=TELCO1$ &
	\ STATION.TELCO2$(FREE%)=TELCO2$ &
	\ STATION.CLASS$(FREE%)=S.CLASS$ &
	\ STATION.ACTION$(FREE%)=S.ACTION$ &
	\ STATION.DESCRIPTION$(FREE%)=S.DESCRIPTION$ &
	\ POSTFIX$=REDEF.MSG$ &
	\ POSTFIX$=DEF.MSG$ IF E% &
	\ MSG$=STATION.MSG$+STATION$+POSTFIX$ &
	\ GOTO 9100 &
		! OPEN STATION FILE AND LOOP TIL WRITE ACCESS GRANTED &
		! PURGE CURRENT STATION ENTRY &
		! EXIT IF NO SPACE FOR NEW ENTRY &
		! DEFINE OR REDEFINE THE STATION &
		! DISPLAY CONFIRMATION AND EXIT &

5390	CLOSE 2% &
	\ Z%=FND%(WAIT.MSG$+STATION.MSG$+FILE.MSG$) IF TMR%=2% &
	\ SLEEP 2% &
	\ TMR%=TMR%+1% &
	\ GOTO 5310 &
		! LOOP WAITING FOR WRITE ACCESS TO STATION DATA FILE &
		! DISPLAY WAITING ... MESSAGE IF DELAY LONGER THAN 4 SECONDS &

5400	! &
	&
	!	LIST STATION &

5410	OPEN STATION.FILE$ FOR INPUT AS FILE 2%, MODE 8192% &
	\ HEADER.FLAG%=-1% &
	\ GOTO 5430 UNLESS LEN(STATION$) &
	\ GOSUB 5800 &
	\ GOTO 9000 IF E% &
		! OPEN STATION FILE READ ONLY &
		! GO TO LOOP IF LISTING ALL STATIONS &
		! SEARCH FOR SPECIFIC STATION TO LIST &
		! EXIT IF STATION NOT FOUND &

5420	GOSUB 5910 &
	\ GOSUB 5920 &
	\ MSG$=NULL$ &
	\ GOTO 9100 &
		! LIST DATA FOR SPECIFIC STATION AND EXIT &

5430	FOR SNDX%=1% TO 255% &
	\ GOTO 5440 UNLESS LEN(STATION.NAME$(SNDX%)) &
	\ GOSUB 5900 &
	\ GOSUB 5500 &
		! LIST DATA FOR ALL STATIONS &

5440	NEXT SNDX% &
	\ MSG$=NULL$ &
	\ MSG$="There are No Stations Defined" IF HEADER.FLAG% &
	\ GOTO 9100 &
		! DISPLAY MSG AND EXIT IF NO STATIONS DEFINED &

5500	PRINT #LOGF%, STATION.HEADER$ IF HEADER.FLAG% &
	\ HEADER.FLAG%=0% &
	\ PRINT #LOGF%, TAB( 0%);LEFT(STATION$,10%); &
	\ PRINT #LOGF%, TAB(11%);LEFT(TELCO1$,24%); &
	\ PRINT #LOGF%, TAB(36%);LEFT(S.CLASS$,7%); &
	\ PRINT #LOGF%, TAB(44%);LEFT(S.ACTION$,7%); &
	\ PRINT #LOGF%, TAB(52%);LEFT(S.DESCRIPTION$,28%); &
	\ PRINT #LOGF% &
	\ PRINT #LOGF%, TAB(11%);LEFT(TELCO2$,24%) IF LEN(TELCO2$) &
	\ RETURN &
		! PRINT HEADER LINE IF FIRST TIME THRU &
		! LIST STATION DATA FOR A SPECIFIC STATION &

5600	! &
	&
	!	PURGE STATION COMMAND &

5610	TMR%=0% &

5620	OPEN STATION.FILE$ AS FILE 2% &
	\ GOTO 5690 IF STATUS AND 1024% &
	\ GOSUB 5800 &
	\ GOTO 9000 IF E% &
	\ GOSUB 5910 &
	\ GOSUB 5920 &
	\ GOSUB 5700 &
	\ MSG$=STATION.MSG$+STATION$+PURGED.MSG$ &
	\ GOTO 9100 &
		! OPEN AND WAIT FOR WRITE ACCESS TO STATION FILE &
		! PURGE STATION IDENTIFIED BY NAME &
		! DISPLAY MSG AND EXIT IF STATION WAS NOT DEFINED &
		! DISPLAY INFO FOR STATION THAT WAS PURGED &
		! DISPLAY CONFIRMATION AND EXIT &

5690	CLOSE 2% &
	\ Z%=FND%(WAIT.MSG$+STATION.MSG$+FILE.MSG$) IF TMR%=2% &
	\ SLEEP 2% &
	\ TMR%=TMR%+1% &
	\ GOTO 5620 &
		! WAIT 2 SECONDS AND RETRY OPEN TO GET WRITE ACCESS &
		! DISPLAY WAITING ... MESSAGE IF DELAY LONGER THAN 4 SECONDS &

5700	STATION.NAME$(SNDX%)=NULL$ &
	\ STATION.TELCO1$(SNDX%)=NULL$ &
	\ STATION.TELCO2$(SNDX%)=NULL$ &
	\ STATION.CLASS$(SNDX%)=NULL$ &
	\ STATION.ACTION$(SNDX%)=NULL$ &
	\ STATION.DESCRIPTION$(SNDX%)=NULL$ &

5720	RETURN &

5800	! &
	&
	!	SEARCH FOR STATION BY NAME &

5810	FREE%,E%=0% &
	\ MSG$=NULL$ &

5820	FOR SNDX%=1% TO 255% &
	\ GOTO 5830 IF STATION$<>STATION.NAME$(SNDX%) &
	\ FREE%=SNDX% &
	\ GOTO 5890 &

5830	FREE%=SNDX% IF FREE%=0% AND STATION.NAME$(SNDX%)=NULL$ &

5840	NEXT SNDX% &
	\ E%=-1% &
	\ MSG$=STATION.MSG$+STATION$+NDF.MSG$ &

5890	RETURN &
	&

5900	STATION$=STATION.NAME$(SNDX%) &

5910	TELCO1$=STATION.TELCO1$(SNDX%) &
	\ TELCO2$=STATION.TELCO2$(SNDX%) &
	\ S.CLASS$=STATION.CLASS$(SNDX%) &
	\ S.ACTION$=STATION.ACTION$(SNDX%) &
	\ S.DESCRIPTION$=STATION.DESCRIPTION$(SNDX%) &
	\ RETURN &

5920	Z%=FND%(STATION.NAME.MSG$+"= "+STATION$) &
	\ Z%=FND%(STATION.TELCO1.MSG$+"= "+TELCO1$) &
	\ Z%=FND%(STATION.TELCO2.MSG$+"= "+TELCO2$) &
	\ Z%=FND%(STATION.CLASS.MSG$+"= "+S.CLASS$) &
	\ Z%=FND%(STATION.ACTION.MSG$+"= "+S.ACTION$) &
	\ Z%=FND%(STATION.DESCRIPTION.MSG$+"= "+S.DESCRIPTION$) &
	\ RETURN &

6000	! &
	&
	!	HANDLE PORT COMMANDS &

6010	GOTO 6020 IF FNGETKWD% &
	\ PORT$=NULL$ &
	\ GOTO 6030 IF CMD%=2% &
	\ PRINT #1% &
	\ PRINT #1%, PORT.NAME.MSG$;"? "; &
	\ INPUT #1%, PORT$ &
	\ PORT$=CVT$$(PORT$,252%) &
	\ GOTO 6030 &

6020	PORT$=KWD$ &
	\ Z%=FND%(PORT.NAME.MSG$+fnprmpt$(PORT$)) IF CMD%=1% &

6030	ON CMD% GOTO 6100,6400,6600 &
		! DISPATCH TO DEFINE PORT, &
		!	      LIST   PORT, &
		!	   OR PURGE  PORT &

6100	! &
	&
	!	DEFINE PORT &

6110	CHANGE.FLAG%=0% &
	\ OPEN PORT.FILE$ FOR INPUT AS FILE 3%, MODE 8192% &
	\ ID$=NULL$ &
	\ P.CLASS$=NULL$ &
	\ DEVICE$=NULL$ &
	\ P.ACTION$="SETDTR" &
	\ P.DESCRIPTION$=NULL$ &
	\ GOSUB 6800 &
	\ GOSUB 6910 UNLESS e% &
		! OPEN PORT FILE READ ONLY &
		! GET CURRENT PORT INFO IF ALREADY DEFINED &
		! INSURE THERE IS A FREE SLOT FOR NEW DEFINITION &

6130	CLOSE 3% &
	\ MSG$=NO.SPACE$ &
	\ GOTO 9000 UNLESS FREE% &
	\ PRINT #1%, PORT.ID.MSG$;fnprmpt$(ID$); &
	\ INPUT LINE #1%, NEW.ID$ &
	\ NEW.ID$=CVT$$(NEW.ID$,252%) &
	\ GOTO 6130 UNLESS LEN(ID$)+LEN(NEW.ID$) &
	\ GOTO 6150 UNLESS LEN(NEW.ID$) &
	\ OLD.ID$=ID$ &
	\ ID$=NEW.ID$ &
	\ GOSUB 14100 &
	\ GOTO 6140 UNLESS e% &
	\ ID$=OLD.ID$ &
	\ GOTO 6130 &
		! EXIT IF NO SLOTS AVAILABLE FOR NEW PORT ENTRY &
		! PROMPT FOR PORT IDENTIFIER &
		! VERIFY PORT IDENTIFIER FOR CORRECT SYNTAX &
		! REPROMPT IF ILLEGAL. SET CHANGE FLAG IF OKAY. &

6140	CHANGE.FLAG%=-1% &

6150	PRINT #1%, PORT.CLASS.MSG$;fnprmpt$(p.CLASS$); &
	\ INPUT LINE #1%, NEW.CLASS$ &
	\ NEW.CLASS$=CVT$$(NEW.CLASS$,252%) &
	\ GOTO 6150 UNLESS LEN(p.CLASS$)+LEN(NEW.CLASS$) &
	\ GOTO 6170 UNLESS LEN(NEW.CLASS$) &
	\ P.CLASS$=NEW.CLASS$ &
	\ CHANGE.FLAG%=-1% &
		! PROMPT FOR PORT CLASS &
		! REPROMPT IF ILLEGAL. SET CHANGE FLAG IF OKAY. &

6170	PRINT #1%, PORT.ACTION.MSG$;fnprmpt$(p.ACTION$); &
	\ INPUT LINE #1%, NEW.ACTION$ &
	\ NEW.ACTION$=CVT$$(NEW.ACTION$,252%) &
	\ GOTO 6170 UNLESS LEN(p.ACTION$)+LEN(NEW.ACTION$) &
	\ GOTO 6200 UNLESS LEN(NEW.ACTION$) &
	\ OLD.ACTION$=P.ACTION$ &
	\ P.ACTION$=NEW.ACTION$ &
	\ GOSUB 7100 &
	\ GOTO 6180 UNLESS e% &
	\ Z%=FND%(MSG$) &
	\ P.ACTION$=OLD.ACTION$ &
	\ GOTO 6170 &
		! PROMPT FOR PORT ACTION ROUTINE &
		! REPROMPT IF ILLEGAL. SET CHANGE FLAG IF OKAY. &

6180	CHANGE.FLAG%=-1% &

6200	PRINT #1%, PORT.DEVICE.MSG$;fnprmpt$(DEVICE$); &
	\ INPUT LINE #1%, NEW.DEVICE$ &
	\ NEW.DEVICE$=CVT$$(NEW.DEVICE$,252%) &
	\ GOTO 6200 UNLESS LEN(DEVICE$)+LEN(NEW.DEVICE$) &
	\ GOTO 6220 UNLESS LEN(NEW.DEVICE$) &
	\ DEVICE$=NEW.DEVICE$ &
	\ CHANGE.FLAG%=-1% &
		! PROMPT FOR PORT DEVICE &
		! REPROMPT IF ILLEGAL. SET CHANGE FLAG IF OKAY. &

6220	PRINT #1%, PORT.DESCRIPTION.MSG$;fnprmpt$(p.DESCRIPTION$); &
	\ INPUT LINE #1%, NEW.DESCRIPTION$ &
	\ NEW.DESCRIPTION$=CVT$$(NEW.DESCRIPTION$,20%)		!4%+16% &
	\ GOTO 6240 UNLESS LEN(NEW.DESCRIPTION$) &
	\ P.DESCRIPTION$=CVT$$(NEW.DESCRIPTION$,156%) &
	\ CHANGE.FLAG%=-1% &
		! PROMPT FOR PORT DESCRIPTION &
		! REPROMPT IF ILLEGAL. SET CHANGE FLAG IF OKAY. &

6240	GOTO 6300 &
		! FUTURE PORT QUERIES GO HERE &

6300	MSG$=PORT.MSG$+PORT$+NO.CHANGE$ &
	\ GOTO 9100 UNLESS CHANGE.FLAG% &
	\ TMR%=0% &
		! DISPLAY MESSAGE AND EXIT IF NO CHANGE TO PORT DATA &

6310	OPEN PORT.FILE$ AS FILE 3% &
	\ GOTO 6390 IF STATUS AND 1024% &
	\ GOSUB 6800 &
	\ MSG$=NO.SPACE$ &
	\ GOTO 9000 UNLESS FREE% &
	\ PORT.NAME$(FREE%)=PORT$ &
	\ PORT.ID$(FREE%)=ID$ &
	\ PORT.CLASS$(FREE%)=P.CLASS$ &
	\ PORT.ACTION$(FREE%)=P.ACTION$ &
	\ PORT.DEVICE$(FREE%)=DEVICE$ &
	\ PORT.DESCRIPTION$(FREE%)=P.DESCRIPTION$ &
	\ POSTFIX$=REDEF.MSG$ &
	\ POSTFIX$=DEF.MSG$ IF E% &
	\ MSG$=PORT.MSG$+PORT$+POSTFIX$ &
	\ GOTO 9100 &
		! OPEN PORT FILE AND LOOP TIL WRITE ACCESS GRANTED &
		! PURGE CURRENT PORT ENTRY &
		! EXIT IF NO SPACE FOR NEW ENTRY &
		! DEFINE OR REDEFINE THE PORT &
		! DISPLAY CONFIRMATION AND EXIT &

6390	CLOSE 3% &
	\ Z%=FND%(WAIT.MSG$+PORT.MSG$+FILE.MSG$) IF TMR%=2% &
	\ SLEEP 2% &
	\ TMR%=TMR%+1% &
	\ GOTO 6310 &
		! LOOP WAITING FOR WRITE ACCESS TO PORT DATA FILE &
		! DISPLAY WAITING ... MESSAGE IF DELAY LONGER THAN 4 SECONDS &

6400	! &
	&
	!	LIST PORT &

6410	OPEN PORT.FILE$ FOR INPUT AS FILE 3%, MODE 8192% &
	\ HEADER.FLAG%=-1% &
	\ GOTO 6430 UNLESS LEN(PORT$) &
	\ GOSUB 6800 &
	\ GOTO 9000 IF E% &
		! OPEN PORT FILE READ ONLY &
		! GO TO LOOP IF LISTING ALL PORTS &
		! SEARCH FOR SPECIFIC PORT TO LIST &
		! EXIT IF PORT NOT FOUND &

6420	GOSUB 6910 &
	\ GOSUB 6920 &
	\ MSG$=NULL$ &
	\ GOTO 9100 &
		! LIST DATA FOR SPECIFIC PORT AND EXIT &

6430	FOR PNDX%=1% TO 63% &
	\ GOTO 6440 unless len(PORT.NAME$(PNDX%)) &
	\ GOSUB 6900 &
	\ GOSUB 6500 &
		! LIST DATA FOR ALL PORTS &

6440	NEXT PNDX% &
	\ MSG$=NULL$ &
	\ MSG$="There are No Ports Defined" IF HEADER.FLAG% &
	\ GOTO 9100 &
		! DISPLAY MSG AND EXIT IF NO PORTS DEFINED &

6500	PRINT #LOGF%, PORT.HEADER$ IF HEADER.FLAG% &
	\ HEADER.FLAG%=0% &
	\ PRINT #LOGF%, TAB( 0%);LEFT(PORT$,10%); &
	\ PRINT #LOGF%, TAB(11%);LEFT(ID$,24%); &
	\ PRINT #LOGF%, TAB(36%);LEFT(P.CLASS$,7%); &
	\ PRINT #LOGF%, TAB(44%);LEFT(P.ACTION$,7%); &
	\ PRINT #LOGF%, TAB(52%);LEFT(DEVICE$,7%); &
	\ PRINT #LOGF%, TAB(60%);LEFT(P.DESCRIPTION$,20%); &
	\ PRINT #LOGF% &
	\ RETURN &
		! DISPLAY HEADER LINE IF FIRST TIME THRU &
		! LIST PORT DATA FOR A SPECIFIC PORT &

6600	! &
	&
	!	PURGE PORT &

6610	TMR%=0% &

6620	OPEN PORT.FILE$ AS FILE 3% &
	\ GOTO 6690 IF STATUS AND 1024% &
	\ GOSUB 6800 &
	\ GOTO 9000 IF e% &
	\ GOSUB 6910 &
	\ GOSUB 6920 &
	\ GOSUB 6700 &
	\ MSG$=PORT.MSG$+PORT$+PURGED.MSG$ &
	\ GOTO 9100 &
		! OPEN AND WAIT FOR WRITE ACCESS TO PORT FILE &
		! PURGE PORT IDENTIFIED BY NAME &
		! DISPLAY MSG AND EXIT IF PORT WAS NOT DEFINED &
		! DISPLAY INFO FOR PORT THAT WAS PURGED &
		! DISPLAY CONFIRMATION AND EXIT &

6690	CLOSE 3% &
	\ Z%=FND%(WAIT.MSG$+PORT.MSG$+FILE.MSG$) IF TMR%=2% &
	\ SLEEP 2% &
	\ TMR%=TMR%+1% &
	\ GOTO 6620 &
		! WAIT 2 SECONDS AND RETRY OPEN TO GET WRITE ACCESS &
		! DISPLAY WAITING ... MESSAGE IF DELAY LONGER THAN 4 SECONDS &
	&

6700	PORT.NAME$(PNDX%)=NULL$ &
	\ PORT.ID$(PNDX%)=NULL$ &
	\ PORT.CLASS$(PNDX%)=NULL$ &
	\ PORT.ACTION$(PNDX%)=NULL$ &
	\ PORT.DEVICE$(PNDX%)=NULL$ &
	\ PORT.DESCRIPTION$(PNDX%)=NULL$ &

6720	RETURN &

6800	! &
	&
	!	SEARCH FOR PORT BY NAME &

6810	FREE%,E%=0% &
	\ MSG$=NULL$ &

6820	FOR PNDX%=1% TO 63% &
	\ GOTO 6830 IF PORT$<>PORT.NAME$(PNDX%) &
	\ FREE%=PNDX% &
	\ GOTO 6890 &

6830	FREE%=PNDX% IF FREE%=0% AND PORT.NAME$(PNDX%)=NULL$ &

6840	NEXT PNDX% &
	\ E%=-1% &
	\ MSG$=PORT.MSG$+PORT$+NDF.MSG$ &

6890	RETURN &

6900	PORT$=PORT.NAME$(PNDX%) &

6910	ID$=PORT.ID$(PNDX%) &
	\ P.CLASS$=PORT.CLASS$(PNDX%) &
	\ P.ACTION$=PORT.ACTION$(PNDX%) &
	\ DEVICE$=PORT.DEVICE$(PNDX%) &
	\ P.DESCRIPTION$=PORT.DESCRIPTION$(PNDX%) &
	\ RETURN &

6920	Z%=FND%(PORT.NAME.MSG$+"= "+PORT$) &
	\ Z%=FND%(PORT.ID.MSG$+"= "+ID$) &
	\ Z%=FND%(PORT.CLASS.MSG$+"= "+P.CLASS$) &
	\ Z%=FND%(PORT.ACTION.MSG$+"= "+P.ACTION$) &
	\ Z%=FND%(PORT.DEVICE.MSG$+"= "+DEVICE$) &
	\ Z%=FND%(PORT.DESCRIPTION.MSG$+"= "+P.DESCRIPTION$) &
	\ RETURN &

7000	! &
	&
	!	DISPATCH TO PORT ACTION ROUTINES &

7010	E%=0% &
	\ GOTO 7200 IF P.ACTION$="NONE" &
	\ GOTO 7300 IF P.ACTION$="SETDTR" &
	\ GOTO 7400 IF P.ACTION$="DECNET" &
	\ GOTO 7600 IF P.ACTION$="2780" &

7020	GOTO 7180 &
	&

7100	! &
	&
	!	CHECK FOR SUPPORTED PORT ACTION ROUTINES &

7110	E%=0% &
	\ GOTO 7190 IF P.ACTION$="NONE" &
	\ GOTO 7190 IF P.ACTION$="SETDTR" &
	\ GOTO 7190 IF P.ACTION$="DECNET" &
	\ GOTO 7190 IF P.ACTION$="2780" &

7180	MSG$="Port Action Routine   "+P.ACTION$+" is not Defined" &
	\ E%=-1% &

7190	RETURN &

7200	! &
	&
	!	DEFAULT PORT ACTION ROUTINE = "NONE" &

7210	GOSUB 14200 &
	\ RETURN &
		! JUST DIAL THE NUMBER &
		! RETURN ANY ERROR REPORTED BY DIALER &

7300	! &
	&
	!	PORT ACTION ROUTINE "SETDTR" &

7310	E%=-1% &
	\ MSG$="Illegal Physical Device for SETDTR Action Routine" &
	\ GOTO 7390 IF LEFT(DEVICE$,2%)<>"KB" &
	\ GOTO 7314 UNLESS callback% AND (NOT detached%) &
	\ PRINT #1%, CHR$(13%);CHR$(10%);"   Detaching...." &
	\ logf%=4% &
	\ logf$="0"+NUM1$(job%) &
	\ logf$=":DIAL"+RIGHT(logf$,LEN(logf$)-1%)+".LOG<40>" &
	\ OPEN logf$ AS FILE logf%, MODE 2% &
	\ PRINT #logf%, CHR$(12%)
7311	ON ERROR GOTO 7312 &
	\ z$=SYS(CHR$(6%)+CHR$(7%)+CHR$(128%)) &
	\ GOTO 7313
7312	ON ERROR GOTO 19000 &
	\ RESUME 7313
7313	detached%=-1% &
	\ z%=fnhangup.kb%(kb0%) &

7314	KB$=DEVICE$ &
	\ KB%=VAL(RIGHT(DEVICE$,3%)) &

7315	PRINT #LOGF%, "Keyboard = ";KB$ &

7320	IF connect% THEN &
		ON ERROR GOTO 7323 &
	\	assigned%=0% &
	\	z$=SYS(CHR$(6%)+CHR$(10%)+STRING$(20%,0%)+"KB"+CHR$(kb%)+CHR$(255%)) &
	\	assigned%=-1% &
		! ASSIGN THE KB: (IF POSSIBLE)
7322	ON ERROR GOTO 19000 &
	\ GOTO 7340
7323	e%=-1% &
	\ msg$=null$ &
	\ z%=fnd%(remote.busy$) &
	\ z$=SYS(CHR$(6%)+CHR$(11%)+STRING$(20%,0%)+"KB"+CHR$(kb%)+CHR$(255%)) IF assigned% &
	\ RESUME 7390 &
		! deassign the KB: (IF ASSIGNED) &

7340	z%=fnsetdtr%(kb%) &
	\ E%=0% &
	\ MSG$=NULL$ &
	\ GOSUB 14200 &

7390	ON ERROR GOTO 19000 &
	\ RETURN &

7400	! &
	&
	!	PORT ACTION ROUTINE = "DECNET" &

7410	GOTO 7200 &
		! CURRENTLY DEFAULTS TO "NONE" &

7600	! &
	&
	!	PORT ACTION ROUTINE = "2780" &

7610	GOTO 7200 &
		! CURRENTLY DEFAULTS TO "NONE" &

9000	! &
	&
	!	EXIT PROCESSING &

9010	E%=1% &

9100	PRINT #LOGF%, MSG$ IF LEN(MSG$) &
	\ CLOSE 1%,2%,3%,9% &
	\ GOTO 32700 IF E0% &
	\ GOTO 2000 &

10000	! &
	&
	!	S U B R O U T I N E S &
	&
	&

10010	!------------------------------------------------------------! &
	!	GET package device & ppn &
	!------------------------------------------------------------!
10020	CHANGE SYS(CHR$(12%)) TO m%		!last OPEN FILE stats &
	\ device.ppn$="["+NUM1$(m%(6%))+","+NUM1$(m%(5%))+"]" &
	\ device.ppn$="_"+CHR$(m%(23%))+CHR$(m%(24%))+NUM1$(m%(25%))+":"+device.ppn$ &
		IF m%(26%) AND 1% &
	\ IF m%(3%)+SWAP%(m%(4%))<>15%*2% THEN &
		PRINT "?DIALER must be RUN" &
	\	GOTO 32767 &
		! BUILD NAME OF DEVICE AND ACCOUNT OF LAST OPENED FILE. &
		! WE MUST HAVE COME FROM A COMPILED FILE SO WE CAN BE &
		! SURE THAT THIS NAME IS REALLY OUR PACKAGE LOCATION.
10030	RETURN &

10100	! &
	&
	!	DEFINE TEXT FOR MESSAGES &
	&

10110	CRLF$=CHR$(13%)+CHR$(10%) &
	\ NULL$="" &
	\ ERR.SYNTAX$="?Command Syntax Error" &

10120	ADAPTER.BUSY$="Dialer Control Line Busy - Try Again Later" &
	\ NO.ANS.TONE$="No Answer Tone Detected - Abandon Call" &
	\ NO.DIAL.TONE$="No Dial Tone at modem" &
	\ NO.RESPONSE$="Dialer or Adaptor timeout - Abandon Call" &
	\ DIAL.CHANGE.SPEED$="Modem changed speed" &
	\ DIAL.FMT.ERR$="Format Error in Data Presented to Dialer" &
	\ DIAL.PAR.ERR$="Parity Error in Data Presented to Dialer" &
	\ DIAL.MEM.OVF$="Dialer or Adaptor Memory Overflow" &
	\ REMOTE.BUSY$="Modem, PBX, or Remote Busy - Try Again Later" &
	\ RESPONSE.BAD$="Unrecognized Response Received From Dialer" &
	\ CALL.COMPLETE$="Connection Made - Call Complete" &
	\ VADIC$="VADIC " &
	\ NO.SPACE$="No Space for New Entry" &
	\ NO.CHANGE$=" Left Unchanged" &
	\ PURGED.MSG$=" Purged" &
	\ WAIT.MSG$="Waiting for Write Access to " &
	\ FILE.MSG$="Data File" &
	\ QUAL.MSG$=" Command Requires STATION or PORT Qualifier" &
	\ REDEF.MSG$=" Redefined" &
	\ DEF.MSG$=" Defined" &
	\ NDF.MSG$=" is not Defined" &
	\ INIT.MSG$=" Initialized" &
	\ ERR.TELCO.MSG$="Telephone Number " &
	\ ERR.TOO.LONG$=" is too Long" &
	\ BAD.CHARS$=" Contains Illegal Characters" &
	&

10130	STATION.MSG$="Station " &
	\ STATION.NAME.MSG$   ="Station Symbolic Name  " &
	\ STATION.TELCO1.MSG$ ="Xmit Telephone Number  " &
	\ STATION.TELCO2.MSG$ ="Recv Telephone Number  " &
	\ STATION.CLASS.MSG$  ="Port Class             " &
	\ STATION.ACTION.MSG$ ="Station Action Routine " &
	\ STATION.DESCRIPTION.MSG$="Station Description    " &

10140	PORT.MSG$="Port " &
	\ PORT.NAME.MSG$   ="Port Symbolic Name  " &
	\ PORT.ID.MSG$     ="Port Identifier     " &
	\ PORT.CLASS.MSG$  ="Port Class          " &
	\ PORT.ACTION.MSG$ ="Port Action Routine " &
	\ PORT.DEVICE.MSG$ ="Physical Device     " &
	\ PORT.DESCRIPTION.MSG$="Port Description    " &

10160	STATION.HEADER$="STATION    TELEPHONE NUMBER(s)      "+ &
			"CLASS   ACTION  DESCRIPTION"+CRLF$ &
	\ PORT.HEADER$ ="PORT       DIALER PORT IDENTIFIER   "+ &
			"CLASS   ACTION  DEVICE  DESCRIPTION"+CRLF$ &

10390	RETURN &

11000	! &
	&
	!	TELEPHONE NUMBER SUBROUTINES &

11100	! &
	&
	!	CHECK TELEPHONE NUMBER FOR CORRECT SYNTAX &

11110	SQUASH%=0% \ GOTO 11220 &

11200	! &
	&
	!	SQUASH TELEPHONE NUMBER TO ESSENTIALS &

11210	SQUASH%=-1% &

11220	E%=0% &
	\ L%=LEN(TELCO$) &
	\ GOTO 11240 IF L%<=32% &
	\ MSG$=ERR.TELCO.MSG$+TELCO$+ERR.TOO.LONG$ &
	\ E%=-1% &
	\ GOTO 11290 &

11240	CHANGE TELCO$ TO TELCO% &
	\ FOR I%=1% TO L% &

11250	T%=TELCO%(I%) &
	\ GOTO 11280 IF T% >= ASCII("0") AND T% <= ASCII("9") &
	\ GOTO 11280 IF T%  = ASCII("#") &
	\ GOTO 11280 IF T%  = ASCII(",") &
	\ GOTO 11270 IF T%=ASCII("(") OR T%=ASCII(")") OR T%=ASCII("-") &
	\ GOTO 11280 IF T%=ASCII("T") &
	\ GOTO 11280 IF T%=ASCII("P") &
	\ GOTO 11280 IF T%=ASCII("=") &
	\ GOTO 11280 IF T%=ASCII("!") &
		! ACCEPT DIGITS 0 to 9 &
		! RETAIN TANDEM DIAL DIGIT # &
		! RETAIN COMMA TO SEPARATE NUMBERS &
		! DISCARD PARENS AND DASHES &
		! RETAIN TRANSFER TO MODEM FLAG (T TERMINATOR) &

11260	MSG$=ERR.TELCO.MSG$+TELCO$+BAD.CHARS$ &
	\ E%=-1% &
	\ GOTO 11290 &

11270	TELCO%(I%)=0% IF SQUASH% &

11280	NEXT I% &
	\ CHANGE TELCO% TO TELCO$ &
	\ TELCO$=CVT$$(TELCO$,4%) &

11290	RETURN &

14100	! &
	&
	!	DISPATCH TO VERIFICATION ROUTINES FOR PORT IDENTIFIERS &

14110	E%=0% &
	\ P$=LEFT(ID$,2%) &

14120	GOTO 15100   IF P$="VA" &
	\ GOTO 16100 IF P$="AR" &
	\ GOTO 17100 IF P$="DF" &

14190	Z%=FND%("Unsupported Dialer Type") &
	\ E%=-1% &
	\ RETURN &

14200	! &
	&
	! 	DISPATCH TO APPROPRIATE DIALER TO DIAL NUMBER &

14210	P$=LEFT(ID$,2%) &
	\ old.telco1$=telco1$+"," &
	\ new.telco$=null$ &
	\ GOTO 14220 &

14215	z%=fnhangup.kb%(kb%) &
	\ z%=fnsetdtr%(kb%) IF p.action$="SETDTR" &
		! hangup up data set &
		! set data terminal ready (DTR if appropriate) &

14220	E%=0% &
	\ comma%=INSTR(1%,old.telco1$,",") &
	\ ext$=LEFT(old.telco1$,comma%-1%) &
	\ old.telco1$=RIGHT(old.telco1$,comma%+1%) &
	\ new.telco$,telco$=LEFT(new.telco$,LEN(new.telco$)-LEN(ext$))+ext$ &
	\ GOTO 14220 UNLESS LEN(telco$) &

14225	i%=0% &
	\ i%=1% IF p$="VA" &
	\ i%=2% IF p$="AR" &
	\ i%=3% IF p$="DF" &
	\	STOP unless i% &
	\ ON i%	GOSUB 15200,16200,17200 &
	\ GOTO 14290 UNLESS e% &
	\ GOTO 14215 IF LEN(old.telco1$) &
	\ IF connect% THEN &
		z$=SYS(CHR$(6%)+CHR$(11%)+STRING$(20%,0%)+"KB"+CHR$(kb%)+CHR$(255%)) &
	\	assigned%=0% &
	\	z$=SYS(CHR$(6%)+CHR$(16%)+CHR$(0%)+CHR$(kb%)+STRING$(4%,0%) &
			+CHR$(255%)+CHR$(128%)+STRING$(6%,0%)	!xon,echo &
			+CHR$(255%)+STRING$(3%,0%)		!stall &
			+CHR$(0%)+STRING$(8%,0%))		!(/ring) &
		! deassign kb: (if required) &
		! enable echo on kb: &

14290	RETURN &

15000	! &
	&
	!	VADIC DIALER SUBROUTINES &

15100	! &
	&
	!	CHECK VADIC PORT IDENTIFIER FOR CORRECT SYNTAX &

15110	! &
	! A PORT IDENTIFIER FOR VADIC AUTO-DIAL HARDWARE IS FORMATTED &
	! AS FOLLOWS: &
	! &
	! ID$=VA_dev_da_ma_mt &
	!	WHERE dev IS THE DEVICE SPECIFICATION FOR THE RS232C LINE &
	!	          WHICH CONTROLS THE VA821 ADAPTER &
	!	      da  IS THE DIALER (CHASSIS) ADDRESS (0-3) &
	!	      ma  IS THE MODEM ADDRESS IN CHASSIS (0-14) &
	!	      mt  IS THE MODEM TYPE (103 => 103, 0 => OTHER) &
	! &
	! FOR EXAMPLE: ID$="VA_KB127_3_14_103" &

15120	ON ERROR GOTO 15170 &
	\ E%=0% &
	\ P%=INSTR(1%,ID$,"_") &
	\ P$=RIGHT(ID$,P%+1%) &
	\ GOTO 15180 UNLESS LEN(P$) &
	\ P%=INSTR(1%,P$,"_") &
	\ GOTO 15180 IF P%=0% &
	\ DEV$=LEFT(P$,P%-1%)+":" &

15130	P$=RIGHT(P$,P%+1%) &
	\ GOTO 15180 UNLESS LEN(P$) &
	\ DA$=LEFT(P$,1%) &
	\ DA%=VAL(DA$) &
	\ GOTO 15180 IF DA%>3% OR DA%<0% &

15140	P$=RIGHT(P$,3%) &
	\ GOTO 15180 UNLESS LEN(P$) &
	\ P%=INSTR(1%,P$,"_") &
	\ MA$=LEFT(P$,P%-1%) &
	\ MA%=VAL(MA$) &
	\ GOTO 15180 IF MA%>14% OR MA%<0% &
	\ VAMA$=CHR$(MA%+48%) &

15150	MT$=RIGHT(P$,P%+1%) &
	\ MT%=VAL(MT$) &
	\ GOTO 15180 IF MT%<>103% AND MT%<>0% &
	\ DA%=DA%+4% IF MT%=103% &
	\ VADA$=CHR$(DA%+48%) &
	\ GOTO 15190 &

15170	RESUME 15180 &

15180	MSG$=VADIC$+PORT.ID.MSG$+ID$+BAD.CHARS$ &
	\ E%=-1% &

15190	ON ERROR GOTO 19000 &
	\ RETURN &

15200	! &
	&
	!	DIAL NUMBER WITH VADIC HARDWARE &
	&
	!INPUTS	DEV$ =	DEVICE SPECIFICATION FOR CONTROLLING LINE &
	!      VADA$ =	DIALER ADDRESS FORMATTED FOR VADIC HARDWARE &
	!      VAMA$ =	MODEM  ADDRESS FORMATTED FOR VADIC HARDWARE &
	!     TELCO$ =	TELEPHONE NUMBER TO DIAL (SINGLE DIAL ONLY) &

15210	STX$   = CHR$(128%+2%) &
	\ ETX$ = CHR$(128%+3%) &
	\ SI$  = CHR$(128%+15%) &
	\ EON$ = CHR$(60%) &
	\ SOH$ = CHR$(128%+1%) &
	\ E%   = 0% &

15220	XFER.TO.MODEM%=0% &
	\ L%=LEN(TELCO$) &
	\ IF RIGHT(TELCO$,L%)="T" THEN XFER.TO.MODEM%=-1% &
	\			       TELCO$=LEFT(TELCO$,L%-1%) &

15230	GOSUB 11200 &
	\ CHANGE TELCO$ TO TELCO% &
	\ TELCO%(I%)=ASCII("=") IF TELCO%(I%)=ASCII("#") FOR I%=1% TO L% &
	\ CHANGE TELCO% TO TELCO$ &
		! REPLACE TANDEM DIAL DIGIT # WITH = FOR VADIC HARDWARE &

15240	DIAL$=STX$+VADA$+VAMA$+TELCO$ &
	\ DIAL$=DIAL$+EON$ IF XFER.TO.MODEM% &
	\ DIAL$=DIAL$+SI$+ETX$ &

15300	ON ERROR GOTO 15360 &
	\ OPEN DEV$ AS FILE 9%, MODE 1% &
	\ L%=LEN(DIAL$) &
	\ FIELD #9%, L% AS OUT$ &
	\ LSET OUT$=DIAL$ &
!	\ z%=fnsetdtr%(kb%) IF p.action="SETDTR" &
	\ PUT #9%, RECORD 4096%, COUNT L% &

15305	PRINT #LOGF%, "Waiting for Response (";new.telco$;")" &

15310	FIELD #9%,1% AS RESPONSE$ &
	\ WAIT 120% &
	\ GET #9% &
	\ WAIT 0% &
	\ R$=CVT$$(RESPONSE$,252%) &

15320	GOTO 15330 IF R$<>"A" &
	\ Z%=FND%(CALL.COMPLETE$) &
	\ GOTO 15390 &

15330	E$=RESPONSE.BAD$ &
	\ E$=NO.ANS.TONE$	IF R$="B" &
	\ E$=DIAL.FMT.ERR$	IF R$="D" &
	\ E$=DIAL.PAR.ERR$	IF R$="E" &
	\ E$=DIAL.MEM.OVF$	IF R$="F" &
	\ E$=REMOTE.BUSY$	IF R$="G" &
	\ GOTO 15370 &

15360	E$=null$ &
	\ E%=ERR &
	\ E$=ADAPTER.BUSY$ IF E%=8% AND ERL=15300 &
	\ E$=NO.RESPONSE$ IF E%=15% AND ERL=15310 &
	\ E$="ERR="+NUM1$(E%)+" at line "+NUM1$(ERL) UNLESS LEN(E$) &
	\ WAIT 0% &
	\ RESUME 15380 IF E%=8%		!?Device not available &
	\ RESUME 15370 &

15370	ON ERROR GOTO 19000 &
	\ FIELD #9%, 1% AS out$ &
	\ LSET out$=SOH$ &
	\ PUT #9%, RECORD 4096%, COUNT 1% &
	\ WAIT 120% &
	\ GET #9%, RECORD 4096% &
	\ PRINT #LOGF%, "Got a response = ";out$ UNLESS out$="B" &
	\ WAIT 0% &
		! abort the call if timed-out &

15380	Z%=FND%(E$) &
	\ E%=-1% &

15390	ON ERROR GOTO 19000 &
	\ CLOSE 9% &
	\ RETURN &

16000	! &
	&
	!	ATLANTIC RESEARCH RCS-100 DIALER SUBROUTINES &

16100	! &
	&
	!	CHECK RCS-100 PORT IDENTIFIER FOR CORRECT SYNTAX &

16110	STOP &

16200	! &
	&
	!	DIAL NUMBER WITH ATLANTIC RESEARCH HARDWARE &

16210	STOP &

17000	! &
	&
	!	DF DIALER SUBROUTINES &

17100	! &
	&
	!	CHECK DF PORT IDENTIFIER FOR CORRECT SYNTAX &

17110	! &
	! A PORT IDENTIFIER FOR DF AUTO-DIAL HARDWARE IS FORMATTED &
	! AS FOLLOWS: &
	! &
	! ID$=DF_dev &
	!	WHERE dev IS THE DEVICE SPECIFICATION FOR THE RS232C LINE &
	!	          WHICH CONTROLS THE DF &
	! &
	! FOR EXAMPLE: ID$="DF_KB127" &

17120	ON ERROR GOTO 17170 &
	\ E%=0% &
	\ P%=INSTR(1%,ID$,"_") &
	\ P$=RIGHT(ID$,P%+1%) &
	\ GOTO 17180 UNLESS LEN(P$) &
	\ P%=INSTR(1%,P$,"_") &
	\ GOTO 17180 IF P%<>0% &
	\ DEV$=P$+":" &
	\ GOTO 17190 &

17170	RESUME 17180 &

17180	MSG$="DF"+PORT.ID.MSG$+ID$+BAD.CHARS$ &
	\ E%=-1% &

17190	ON ERROR GOTO 19000 &
	\ RETURN &

17200	! &
	&
	!	DIAL NUMBER WITH DF HARDWARE &
	&
	!INPUTS	DEV$ =	DEVICE SPECIFICATION FOR CONTROLLING LINE &
	!     TELCO$ =	TELEPHONE NUMBER TO DIAL (SINGLE DIAL ONLY) &

17210	STX$   = CHR$(1%) &
	\ E%   = 0% &

17220	! &

17230	GOSUB 11200 &

17240	DIAL$=STX$+TELCO$+CHR$(13%) &

17300	ON ERROR GOTO 17360 &
	\ OPEN DEV$ AS FILE 9%, MODE 1% &
	\ L%=LEN(DIAL$) &
	\ FIELD #9%, L% AS OUT$ &
	\ LSET OUT$=DIAL$ &
	\ PUT #9%, RECORD 4096%, COUNT L% &
	\ PRINT #LOGF%, "Waiting for Response (";new.telco$;")" &

17310	WAIT 120% &
	\ GET #9% &
	\ WAIT 0% &
	\ FIELD #9%, RECOUNT AS RESPONSE$ &

17320	R$=LEFT(CVT$$(RESPONSE$,252%),1%) &
	\ GOTO 17330 IF R$<>"A" &
	\ Z%=FND%(CALL.COMPLETE$) &
	\ GOTO 17390 &

17330	E$=RESPONSE.BAD$ &
	\ E$=NO.ANS.TONE$	IF R$="N" &
	\ E$=DIAL.FMT.ERR$	IF R$="E" &
	\ E$=REMOTE.BUSY$	IF R$="B" &
	\ E$=NO.DIAL.TONE$	IF R$="T" &
	\ E$=DIAL.CHANGE.SPEED$	IF R$="S" &
	\ GOTO 17380 &

17360	wait 0% &
	\ E$=null$ &
	\ E%=ERR &
	\ E$=ADAPTER.BUSY$ IF E%=8% AND ERL=17300 &
	\ E$=NO.RESPONSE$ IF E%=15% AND ERL=17310 &
	\ E$="ERR="+NUM1$(E%)+" at line "+NUM1$(ERL) UNLESS LEN(E$) &
	\ RESUME 17380 &

17380	Z%=FND%(E$) &
	\ E%=-1% &

17390	ON ERROR GOTO 19000 &
	\ CLOSE 9% &
	\ RETURN &

18000	! &
	&
	!	F U N C T I O N S &

18100	DEF* FNGETKWD% &
	\ KWD$=CMD$ &
	\ Z2%=INSTR(1%,CMD$," ") &
	\ IF Z2%=0% THEN CMD$=null$ \ GOTO 18120 &
		! GET NEXT KEYWORD FROM COMMAND STRING &

18110	KWD$=LEFT(CMD$,Z2%-1%) &
	\ CMD$=RIGHT(CMD$,Z2%+1%) &

18120	FNGETKWD%=LEN(KWD$) &
	\ FNEND &
	&

18200	DEF* FNKWD%(Z2$,Z2%)=(INSTR(1%,Z2$,KWD$)=1%) AND (LEN(KWD$)>=Z2%) &
	! FUNCTION:	KEYWORD MATCHING ROUTINE &
	! PARAMETERS:	Z2$	STRING TO MATCH TO. &
	!		Z2%	MINIMUM LENGTH TO MATCH &
	! NO ERRORS EXPECTED &
	&

18300	DEF* FNKWD3%(Z2$)=FNKWD%(Z2$,3%) &
	! FUNCTION:	KEYWORD MATCHING ROUTINE &
	!		MINIMUM OF 3 CHARACTERS &

18310	DEF* FNKWD2%(Z2$)=FNKWD%(Z2$,2%) &
	! FUNCTION:	KEYWORD MATCHING ROUTINE &
	!		MINIMUM OF 2 CHARACTERS &

18400	DEF* FND%(Z$) &
	\ PRINT #LOGF%, Z$ &
	\ FNEND &

18410	DEF* fnprmpt$(z$) &
	\ z$=z$+" " IF LEN(z$) &
	\ fnprmpt$="? "+z$ &
	\ FNEND &

18500	DEF* FNINIT%(F$,FS%) &
	\ FNINIT%,E%=0% &
	\ ON ERROR GOTO 18580 &
	\ OPEN F$ FOR INPUT AS FILE 9%, MODE 8192% &
	\ GOTO 18590 &
		! INITIALIZE STATION OR PORT DATA FILES &
		! IF FILE EXIST, ASSUME ALL IS WELL AND EXIT &

18510	OPEN F$ FOR OUTPUT AS FILE 9%, FILESIZE FS%, MODE 64% &
	\ FIELD #9%, 512% AS ZERO$ &
	\ LSET ZERO$=STRING$(512%,0%) &
	\ PUT #9%, RECORD I% FOR I%=1% TO FS% &
	\ FNINIT%=-1% &
	\ GOTO 18590 &
		! CREATE STATION OR PORT FILE CONDITIONALLY &
		! CONTIGUOUS AND ZERO FILL. &
		! NOTE FILE WAS INITIALIZED AND EXIT &

18580	RESUME 18510 IF ERR=5% AND ERL=18500 &
 	\ E%=ERR &
	\ MSG$=null$ &
	\ RESUME 18590 &

18590	ON ERROR GOTO 19000 &
	\ CLOSE 9% &
	\ FNEND &
	&

18600	DEF* FNQUOTES% &
		! CHECK FOR QUOTED (LITERAL) TELEPHONE NUMBERS AND &
		! DIALER PORT IDENTIFIERS.   STRIP QUOTES IF PRESENT. &
		! FNQUOTES%=0%	IF NO QUOTES (SYMBOLIC NAME) &
		! FNQUOTES%=-1% IF QUOTED    (LITERAL) &

18610	X$=CHR$(ASCII(KWD$)) &
	\ GOTO 18620 IF X$="'" OR X$='"' &
	\ FNQUOTES%=0% &
	\ GOTO 18640 &

18620	KWD$=RIGHT(KWD$,2%) &
	\ X%=LEN(KWD$) &
	\ X$=MID(KWD$,X%,1%) &
	\ KWD$=LEFT(KWD$,X%-1%) IF X$="'" OR X$='"' &
	\ FNQUOTES%=-1% &

18640	FNEND &

18700	DEF* fnhangup.kb%(kb%) &
	\ z$=SYS(CHR$(6%)+CHR$(-9%)+CHR$(kb%)+CHR$(0%)) &
	\ IF detached% THEN SLEEP 30% ELSE SLEEP 5%
18710	FNEND &
		! hangup it up &
		! sleep just to be sure &

18750	DEF* fnsetdtr%(kb%) &
	\ z$=SYS(CHR$(6%)+CHR$(-9%)+CHR$(kb%)+CHR$(-1%)) &
	\ IF connect% THEN &
		z$=SYS(CHR$(6%)+CHR$(16%)+CHR$(0%)+CHR$(kb%)+STRING$(4%,0%) &
			+CHR$(255%)+CHR$(255%)+STRING$(6%,0%)	!xon,no echo &
			+CHR$(255%)+STRING$(3%,0%)		!stall &
			+CHR$(0%)+STRING$(8%,0%))		!(/ring) &
		! turn on data terminal ready (DTR) &
		! disable echo on the terminal (IF connecting)
18760	FNEND &
	&

19000	! &
	&
	&
	!	E R R O R    H A N D L I N G &

19010	E%=ERR &
	\ RESUME 32700 IF E%=11% AND ERL=2010 &
	\ RESUME 9100 IF E%=11% &

19090	PRINT #LOGF%, "ERR=";NUM1$(E%);" at line ";NUM1$(ERL) &
	\ ON ERROR GOTO 0 &
	\ RESUME 32700 &
	&

30000	! &
	&
	&
	!	C C L   E N T R Y &
	&

30010	ON ERROR GOTO 19000 &
	\ cmd$=CVT$$(SYS(CHR$(7%)),444%)	!256%+128%+32%+16%+8%+4%) &
	\ cmd$=RIGHT(cmd$,7%) IF LEFT(cmd$,6%)="DIALER" &
	\ e0%=1% IF LEN(cmd$) &
	\ GOTO 1000 &
		! set up standard error trap. &
		! extract info from core common. &
		! set ccl entry flag if text in command &
		! join common code &
	&

31000	! &
	&
	&
	!	C H A I N    E N T R Y &

31010	ON ERROR GOTO 19000 &
	\ cmd$=CVT$$(SYS(CHR$(7%)),444%)	!256%+128%+32%+16%+8%+4%) &
	\ delim$=LEFT(cmd$,1%) &
	\ i%=INSTR(2%,cmd$,delim$) &
	\ caller$=MID(cmd$,2%,i%-2%) &
	\ called%=LEN(caller$)<>0% &
	\ cmd$=RIGHT(cmd$,i%+1%) &
	\ e0%=1% IF LEN(cmd$) &
	\ entry%=0% &
	\ i%=INSTR(1%,caller$,";") &
	\ GOTO 1000 UNLESS i% &
	\ entry%=VAL(RIGHT(caller$,i%+1%)) &
	\ caller$=LEFT(caller$,i%-1%) &
	\ GOTO 1000 &
		! set up standard error trap. &
		! extract info from core common. &
		! set ccl entry flag if text in cmd &
		! extract caller and entrypoint if possible &
		! join common code &
	&

32700	! &
	&
	&
	!	T E R M I N A T E   P R O G R A M &
	&

32710	CLOSE 4% &
	\ IF called% THEN &
		z$=SYS(CHR$(8%)+CHR$(e%)+CHR$(kb%)) &
	\	CHAIN caller$ LINE entry%
32720	z$=SYS(CHR$(6%)+CHR$(5%)) IF detached% &
		! EXIT with no prompt to kill the DETACHED job &

32767	END
