	.TITLE 	KERMIT
	.SBTTL	S Hecht/D Stevens/R McQueen

;++
; Main module for PRO/Kermit command scanning.  This will communicate
; its desires to the KERFIL.TSK
;--

; Version number

	.IDENT	/1.0.10/

; Directives

	.ENABLE	LC			; Allow lower case ascii strings
	.NLIST	BEX
	.LIBRARY /KERMLB/		; Kermit macro library
	.SBTTL	Revision History

;++
; Version 1.0.00
;
; 1.0.00	Create this module
;
; 1.0.01	By: Robert C. McQueen		On: 15-Feb-1984
;		Clean random routines, delete ones that are not used any more
;		delete global symbols that don't need to be....
;
; 1.0.02	By: Robert C. McQueen		On: 5-March-1984
;		No need to attach to the terminal, so don't do it.
;
; 1.0.03	By: Robert C. McQueen		On: 14-March-1984
;		Redo the inter-task communications.
;
; 1.0.04	By: Robert C. McQueen		On: 19-March-1984
;		Implement support for additional generic commands.
;
; 1.0.05	By: Robert C. McQueen		On: 20-March-1984
;		Change WAIT to SNDPKT to avoid a global symbol conflict.
;
; 1.0.06	By: David Stevens		On: 21-March-1984
;		Change input routines from IO.RVB to IO.RPR, read after
;		prompt.  Also remove useless data locations.  Also fix
;		the check for accepting a null input, and C$GET requires
;		input.
;
; 1.0.07	By: Robert C. McQueen		On: 23-March-1984
;		Make INPUT2 return the correct information.
;
; 1.0.08	By: Robert C. McQueen		On: 27-March-1984
;		Append the positioning strings to the beginning in INPUT and
;		INPUT2.
;
; 1.0.09	By: Robert C. McQueen		On: 5-April-1984
;		Fix the RESUME typeout problem (I hope).
;
; 1.0.10	By: Robert C. McQueen		On: 16-April-1984
;		Move some routines to support KERCON being a seperate task.
;--
	.SBTTL	External symbols

; Get the KERMLB definitions

	.MCALL	KERDEF
	KERDEF				; Get the general symbol definitions
	.MCALL	CHRDEF			; Macro for special character
	CHRDEF				;  definitions (.CHxxx)

	.MCALL	BLSRTN			; Allow use of BLISS macros from
	.MCALL	BLSCAL			;   library
	.MCALL	PJMP
	.MCALL	MSG			; Text definition macro
;
; System routines used in Kermit
;

	.MCALL	QIOW$C
	.MCALL	QIOW$S
	.MCALL	DIR$
	.MCALL	ABRT$C			; Abort task.
	.MCALL	MRKT$S			; Mark time
	.MCALL	ALUN$C			; Assign LUN
	.MCALL	WTSE$S			; Wait for single event flag
	.MCALL	RQST$C			; Request a task (start it up)
	.MCALL	CLEF$S			; Clear event flag
	.SBTTL	Data area for Kermit

;++
; The following are the various flags that are found in KERMIT
;--

	.PSECT	$BYTE$, RW, D

RESFLG:	.BLKB				; Byte flag for resuming typeout
	.SBTTL	Data for Baud rate conversion to ascii

	.PSECT	$PLIT$, RO, D

;
; Data for Senfil system call
;

WLDCRD:	.asciz	'*.*;*'			; Wild card specification.
	.even
WCDLEN:	.word	5			; Number of wildcard parameters.
SDTXT:	.asciz	'Possible files to send:'
	.even				
LSDTXT:	.word	27
PRPT1:	.asciz	'To make selections press SELECT'
	.even
LPRPT1:	.word	37
PRPT2:	.asciz	'Make selection and press DO'
	.even
LPRPT2:	.word	34

	.sbttl	Table for oldfil system call

SENFIL:	.byte	lensfl,0	
	.word	status
	.word	nochos
	.word	files
	.word	fsize
	.word	wldcrd
	.word	wcdlen
	.word	sdtxt
	.word	lsdtxt
	.word	prpt1
	.word	lprpt1
	.word	prpt2
	.word	lprpt2
lensfl=	<.-senfil>/2-1
	.sbttl	Messages
;
; Error messages
;
ERRRQS:	.asciz	'Error trying to run KERFIL - make sure it is installed'
					; Error message for the request
	.even				;   task routine

;
; Messages for Status Display
;

	MSG STAT,<Status of previous transmission>

STATMG:	.ASCII	<.CHCSI>'4;50HLast'<.CHCSI>'4;65HTotal'
	.ASCII	<.CHCSI>'5;50H----'<.CHCSI>'5;65H-----'
	.ASCII	<.CHCSI>'7;5HThe number of bytes sent:'
	.ASCII	<.CHCSI>'8;5HThe number of data bytes sent:'
	.ASCII	<.CHCSI>'9;5HThe number of packets for sent:'
	.ASCII	<.CHCSI>'10;5HThe number of NAK packets sent:'
	.ASCII	<.CHCSI>'11;5HThe number of bytes received:'
	.ASCII	<.CHCSI>'12;5HThe number of data bytes received:'
	.ASCII	<.CHCSI>'13;5HThe number of packets for received:'
	.ASCII	<.CHCSI>'14;5HThe number of NAK packets received:'
	.ASCIZ	<.CHCSI>'23;5HPress RESUME key to continue'<.CHCRT>
	.EVEN


;
; Prompt for input
;

INPHDR:	.ASCII	<.CHCSI>/4;10H/
	.ASCII	/Press MAIN SCREEN or EXIT to return to the main menu/
	.ASCIZ	<.CHCSI>/8;10H/

M$PMT1:	.ASCIZ	<.CHCSI>/12;10H/
M$PMT2:	.ASCIZ	<.CHCSI>/14;10H/

GETTXT:	.ASCII	/      Enter the name of the file(s) you wish to get/
	.ASCII	<.CHCSI>/9;10H/
	.ASCIZ	/      from the remote system and press RETURN/

FILPMT::.ASCIZ	/Remote File Name: /

WRONGK:	.ASCII	<.CHESC>/7/<.CHCSI>/18;10H/
	.ASCIZ	/You pressed the wrong function key.  /<.CHESC>/8/

NOINP:	.ASCII	<.CHESC>/7/<.CHCSI>/18;10H/
	.ASCIZ	/Must be specified !                  /<.CHESC>/8/

I$HDR:	.ASCIZ	/Files To Be Received/
	HDR$L = .-I$HDR
	.EVEN
	.SBTTL	Entry point for KERMIT

;++
; This is the starting point of Pro/Kermit.  The first thing that is done
; is the initialization and then to call the command scanner to do the work.
;--

	.PSECT	$CODE$, RO, I

FROG:	JSR	PC,INICMD		; Initialize the command processing
	JSR	PC,INILIB		; Initialize the library routines
	BLSCAL	TT.INIT			; Initialize terminal processing
	ALUN$C	XKLUN,XK,0,$CODE$	; Assign XK LUN

	JSR	PC,DEFINI		; Initialize the default file processing
	DIR$	#ASSIGN,IOERR		; Do the assign terminal LUN routine
					;   located at assign.
;
; Initialize the intertask communication
;
	MOV	#N$KER,R0		; Claim I'm KERMIT
	MOV	#N$FIL,R1		; And I talk to KERFIL
	JSR	PC,IT$INI		; Initialize intertask
;
; Now and try to start the task
;
	JSR	PC,STAFIL		; Start KERFIL
	BCC	20$			; Branch if not started
;
; Here if the task is already active, determine what to do about it
;
	JSR	PC,CHKACT		; Check active task
;
; Here to do the command scanning
;
20$:	CLR	CONNECT.FLAG		; Clear the connected to own line flag
	JSR	PC,COMMAN		; Process commands
	JSR	PC,EXFIL		; Tell KERFIL to go away
	JMP	EXIT			; Exit this process
	.SBTTL	CHKACT - Check what to do about an active task

;++
; This routine will determine what to do about an active task.
;--

	.PSECT	$CODE$, RO, I

	.GLOBL	CHKACT			; Global routine

CHKACT:	CLRB	RESFLG			; Clear RESUME flag
	BIT	#TRUE,RUN		; Is it really running already?
	BEQ	99$			; No, just return to the caller
	MRKT$S	,#10,#1			; Wait for a ten ticks
	BIT	#TRUE,RUN		; May have been just starting up
	BEQ	99$			; Continue
;
; Here if the task is already running, if that is the case display the menu
; to the user to determine what to do.
;
	JSR	PC,CMDRUN		; Do the command processing for a 
					; KERFIL that is running
	TSTB	RESFLG			; Use resume type out?
	BNE	CHKACT			; Yes, could have exited before done again
	TST	MAIFLG			; User want MAIN SCREEN
	BEQ	99$			; No, don't exit
	JMP	EXIT			; Get out
;
; Now just return to the caller
;
99$:	RTS	PC			; Just return for now

;
; Here if we want to abort the KERFIL task and then try again.
;

CHKABT::MOV	#$TKABT,R0		; Force the KERFIL to abort
	JSR	PC,IT$SND		; Send the data

	BIT	#TRUE,RUN		; Is it really running already?
	BEQ	RET			; No, just return to the caller
	MRKT$S	,#2,#2			; Wait for a two seconds
	BIT	#TRUE,RUN		; Did it shut down?
	BEQ	RET			; Continue
	
	ABRT$C	KERFIL,$CODE$		; Abort the task
	PJMP	STAFIL			; Start KERFIL

RET:	RTS	PC			; Return to the caller
;
; Here if we want to resume the file transfer
;
CHKRES::INCB	RESFLG			; Flag we got a resume
	MOV	#$TKPAI,R0		; Have to paint the screen
	PJMP	SNDPKT			; Send the pack and wait until the 
					;  other end is finished
	.SBTTL	STATUS command

;++
; This routine will output the status information that is kept in the data
; area of KERMSG.  It will paint the box first than fill in the text and
; finally print the numbers in the box.
;
; Usage:
;	JSR	PC,STATUS
;	(Return)
;
;--

STATE::
;
; Attach to the terminal, clear the screen, turn off the cursor, and
;   print out the status message.
;
	BLSCAL	PAINT,<#M$STAT,#STAT$L,#20.>,+ ; Paint the border
	BLSCAL	TT.TEXT,#CUROFF,+	; Turn the cursor off
	BLSCAL	TT.TEXT,#STATMG,-	; Output the text
;
; Reposition the cursor to correspond to the first status message.
;
	MOV	#6,R4			; Set line count at 5.
	JSR	PC,STCRMV		; Jump to status cursor movement.

;
; Take the absolute value of the number of bytes sent, convert it 
;   to decimal, and output it.
;  Reposition the cursor one line down.
;
	MOV	SMSG.TOTAL.CHARS,R2	; Get total chars for this pass
	JSR	PC,CHGDEC		; Call ascii conversion subroutine.
	JSR	PC,STCR65		; Position again
	MOV	SND.TOTAL.CHARS,R2	; Get total since startup
	JSR	PC,CHGDEC		; Print it
	JSR	PC,STCRMV		; Jump to status cursor movement.
;
; Print the number of data characters sent
;
	MOV	SMSG.DATA.CHARS,R2	; Move send data count into R2.
	JSR	PC,CHGDEC		; Call ascii conversion routine.
	JSR	PC,STCR65		; Move out to totals column
	MOV	SND.DATA.CHARS,R2	; Total data sent
	JSR	PC,CHGDEC		; Print the total
	JSR	PC,STCRMV		; Jump to status cursor movement.
;
; Convert the send packet count to decimal and output it.
;  Reposition the cursor one line down.
;
	MOV	SMSG.COUNT,R2		; Move send packet count into R2.
	JSR	PC,CHGDEC		; Call ascii conversion routine.
	JSR	PC,STCR65		; Move to total column
	MOV	SND.COUNT,R2		; Total packet count
	JSR	PC,CHGDEC		; Print it
	JSR	PC,STCRMV		; Jump to status cursor movement.
;
; Print the number of NAK's sent
;
	MOV	SMSG.NAKS,R2		; Move send NAK count into R2.
	JSR	PC,CHGDEC		; Call ascii conversion routine.
	JSR	PC,STCR65		; Move out to totals column
	MOV	SND.NAKS,R2		; Total naks sent
	JSR	PC,CHGDEC		; Print the total
	JSR	PC,STCRMV		; Jump to status cursor movement.
;
; Take the absolute value of the number of bytes received, convert it 
;   to decimal, and output it.
;  Reposition the cursor one line down.
;
	MOV	RMSG.TOTAL.CHARS,R2	; Get total chars for this pass
	JSR	PC,CHGDEC		; Call ascii conversion subroutine.
	JSR	PC,STCR65		; To column 65
	MOV	RCV.TOTAL.CHARS,R2	; Get total since startup
	JSR	PC,CHGDEC		; Print it
	JSR	PC,STCRMV		; Jump to status cursor movement.
;
; Print the number of data characters received
;
	MOV	RMSG.DATA.CHARS,R2	; Move received data count into R2.
	JSR	PC,CHGDEC		; Call ascii conversion routine.
	JSR	PC,STCR65		; Move out to totals column
	MOV	RCV.DATA.CHARS,R2	; Total data received
	JSR	PC,CHGDEC		; Print the total
	JSR	PC,STCRMV		; Jump to status cursor movement.
;
; Convert the receive packet count to decimal and output it.
;  Reposition the cursor one line down.
;
	MOV	RMSG.COUNT,R2		; Move receive packet count into R2.
	JSR	PC,CHGDEC		; Call ascii conversion subroutine.
	JSR	PC,STCR65		; Move out to totals column
	MOV	RCV.COUNT,R2		; Total packets received
	JSR	PC,CHGDEC		; Print the total
	JSR	PC,STCRMV		; Jump to status cursor movement.
;
; Print the number of NAK's received
;
	MOV	RMSG.NAKS,R2		; Move received NAK count into R2.
	JSR	PC,CHGDEC		; Call ascii conversion routine.
	JSR	PC,STCR65		; Move out to totals column
	MOV	RCV.NAKS,R2		; Total naks received
	JSR	PC,CHGDEC		; Print the total
	JSR	PC,STCRMV		; Jump to status cursor movement.
;
; Print out the last error message received.
;
	
	MOV	#17.,R5			; Set for line 17
	MOV	#4,R2			; Set for column 4
	JSR	PC,CURABS		; Position the cursor
	BLSCAL	TT.TEXT,#LAST.ERROR	; Print out the last error message.
;
; Position cursor at line 22, column 1;  turn on the cursor and output
;   everything.  Wait for the resume key to be pressed.
;
	MOV	#22.,R5			; Set for line 18.
	MOV	#1,R2			; Set for column 1.
	JSR	PC,CURABS		; Position the cursor.
	BLSCAL	TT.TEXT,#CURON		; Output the text
	BLSCAL	TT.OUTPUT		; Output any remaining characters
	CALL	WTRES			; Wait for RESUME key to be pressed
					;   before continuing.
	RTS	PC			; Return to the caller

;++
;
; Position cursor for last pass field
;
;--

STCRMV:	INC	R4			; Incrament the line counter.
	MOV	R4,R5			; Put line number into R5
	MOV	#50.,R2			; Put column number into R5.
	PJMP	CURABS			; Move the cursor.

; Position for totals field

STCR65:	MOV	R4,R5			; Get correct line
	MOV	#65.,R2			; And column 65
	PJMP	CURABS			; Position
	.SBTTL	Generic commands -- C$BYE

;++
; This command will instruct KERFIL to send the LOGOUT generic command,
; followed by an instruction to KERFIL to exit and will cause KERMIT to exit
; to P/OS.
;--

C$BYE::	JSR	PC,CHKACT		; Is the other end running?
	JSR	PC,C$LOGO		; Send it to KERFIL
	JSR	PC,EXFIL		; Tell KERFIL to go away
	JMP	EXIT			; Leave KERMIT
	.SBTTL	Generic commands -- C$FINI - Finish command

;++
; This command will instruct KERFIL to send the generic EXIT command to the
; remote KERMIT.  This will then return to the upper level.
;--

C$FINI::JSR	PC,CHKACT		; Is the other end running?
	JSR	PC,CLRGEN		; Clear the generic arguments
	MOV	#GC.EXIT,GENCMD		; Store the generic command
	MOV	#$TKGEN,R0		; Send a generic command to the other
					;  task
	PJMP	SNDPKT			; Send the data and assume it worked
	.SBTTL	Generic commands -- C$LOGO - Logout command

;++
; This command will instruct KERFIL to send the generic LOGOUT command to the
; remote KERMIT.  This will then wait until the remote finishes processing the
; command before returning to the upper level.
;--


C$LOGO::JSR	PC,CHKACT		; Is the other end running?
	JSR	PC,CLRGEN		; Clear the generic arguments
	MOV	#GC.LOGOUT,GENCMD	; Store the generic command
	MOV	#$TKGEN,R0		; Get the function to send
	PJMP	SNDPKT			; Go send command wait until finished
	.SBTTL	C$SERV - Enter server mode

;++
; This routine will insturct the KERFIL task to enter server mode.  It will
; then wait until the remote is finished.
;--

C$SERV::JSR	PC,CHKACT		; Is the other end running?
	MOV	#$TKSRV,R0		; Get the function
	PJMP	SNDPKT			; Send the function to the remote
	.SBTTL	STAFIL - Start KERFIL

;++
; This routine will start the KERFIL task.  It will return only if it was
; able to start KERFIL.
;
; Usage:
;	JSR	PC,STAFIL
;	(Return)
;
; On return:
;	Carry set if active
;	Carry clear if not active
;--

	.PSECT	$CODE$, RO, I

STAFIL:	RQST$C	KERFIL,,,,,$CODE$	; Request task KERFIL to be started
	CMP	@#$DSW,#IS.SUC		; If successful then go on
	BEQ	20$			;
	CMP	@#$DSW,#IE.ACT		; If already active then go on
	BEQ	10$			; Branch if the task is not active
;
; Here if there was some type of error starting the task up
;
	MOV	@#$DSW,STATUS		; Save the status
	CLR	STAT1			; Clear the extra status word
	JMP	RQSERR			; Jump to the fatal error routine
;
; Here if KERFIL was started ok
;
20$:	CLC				; Clear the carry
	RTS	PC			; Return to the caller
;
; Here if KERFIL was already active
;
10$:	SEC				; Set the carry
	RTS	PC			; Return to the caller
	.SBTTL	EXFIL - Cause KERFIL to exit

;++
; This routine will cause KERFIL to exit to P/OS.  This routine is called from
; various levels.
;--


EXFIL::	BIT	#TRUE,RUN		; Is the RUN bit up?
	BEQ	10$			; Branch if it is idle
	RTS	PC			; Otherwise just return

10$:	MOV	#$TKXIT,R0		; Get the exit function
	PJMP	IT$SDA			; Just send the data and go away
	.SBTTL	C$RECV - Send the RECEIVE command to the remote

;++
; This routine will send the RECEIVE command to the KERFIL task.
; The routine will wait until KERFIL acks the information sent to it.
;--

C$RECV::JSR	PC,CHKACT		; Is KERFIL running currently?
	CLR	RCVBUF			; Flag no file
	MOV	#$TKRCV,R0		; Get the function
	PJMP	SNDPKT			; Send the function and wait for reply
	.SBTTL	C$SEND - Send file(s) to the remote Kermit

;++
; Send command processing.  This routine will determine the number of files
; that we have to send to the remote and then send the data to KERXFR to send
; the information.  Note the file specifications are read directly into the
; common.
;
; Usage:
;	JSR	PC,C$SEND
;	(Return)
;
;--

C$SEND::JSR	PC,CHKACT		; Is KERFIL active still?

5$:	MOV	#20.,NOCHOS		; Reset the number of possible choices.
	MOV	#SENFIL,R5		; Set up call to Oldfile sys. routine.
	CALL	OLDFIL			; Call the system routine.

	CMP	STATUS,#ST.KEY		; See if a function key was pressed.
	BNE	10$			; If not a function key then branch.

	CMP	STAT1,#KY.MAI		; See if it was the Main Screen key.
	BEQ	99$			; Exit if it was

	CMP	STAT1,#KY.EXI		; See if it was the Exit key.
	BEQ	99$			; Exit if it was

	BLSCAL	TT.CHAR,#.CHBEL		; Output a bell
	BLSCAL	TT.OUTPUT		; Output any remaining characters
	BR	5$			; Jump back and try again

10$:	MOV	#$TKSND,R0		; Get the function to send to KERFIL
	JSR	PC,SNDPKT		; Send the information and wait for OK
;
; Now to return to the command processing.  We must first reinitialize the
; frame files that are open.
;
99$:	PJMP	INICMD			; Initialize the command processing
	.SBTTL	C$GET - Get a file(s) from the remote Kermit

;++
; This routine will implement the GET command.  It will input the file
; specifications from the user and then call KERFIL to do the work.
;
; Usage:
;	JSR	PC,C$GET
;	(Return)
;
; On return:
;	- Command completed, or
;	- User requested return to KERMIT
;--


C$GET::	JSR	PC,CHKACT		; Is KERFIL active still?
	BLSCAL	INPUT,<#TRUE,#I$HDR,#HDR$L,#GETTXT,#FILPMT>
	TST	R0			; Get a file specification?
	BEQ	10$			; Yes, get the files
	RTS	PC			; Return to the caller

10$:	MOV	#$TKRCV,R0		; Get the function
	PJMP	SNDPKT			; Wait until the other end responds
	.SBTTL	INPUT - Input a line of text from the user

;++
; This routine will paint a box and then prompt the user for a single
; line of input.  The input is left in RCVBUF and the length is left
; in ????.
;
; Usage:
;
;	BLSCAL	INPUT,Flag,Header,Header.lenght,Text,Prompt
;
; Flag - True/False to determine if a null field is allowed.
; Header - Address of the header text.
; Header.length - Number of bytes in the header
; Text - A single line of text to output
; Prompt - Prompt for the user
;
;--

	.PSECT	$CODE$, RO, I

BLSRTN	INPUT,5,<FLAG,HEADER,HDRLEN,TEXT,PROMPT>
	JSR	PC,SETESC		; Allow escape sequences
	MOV	HEADER+2(SP),R0		; Get the header address
	MOV	HDRLEN+2(SP),R1		; And the length
	BLSCAL	PAINT,<R0,R1,#22.>,+	; Put box around prompt.

	BLSCAL	TT.TEXT,#INPHDR,+	; Output the header
	BLSCAL	TT.TEXT,2+..STKO+TEXT(SP),+ ; Output the other text
	BLSCAL	TT.OUTPUT,,-		; Output any remaining characters

	MOV	#M$PMT1,R0		; Build the prompt
	MOV	PROMPT+2(SP),R1		; Put address of prompt into R1.
	JSR	PC,BLDPMT		; Build it
;
; This will now call the routine to read the text from the user's terminal
;
	MOV	FLAG+2(SP),R0		; Get the flag
	JSR	PC,DOINP		; Get the input
	TST	R0			; Normal return ?
	BNE	99$			; No, EXIT of MAIN SCREEN pressed.

	MOV	IOSTAT+2,GEN.1S		; Move the length
	CMP	#MAX.MSG,IOSTAT+2	; Make sure this is small enough
	BGE	10$			; Too big, skip this
	MOV	#MAX.MSG,GEN.1S		; Move the size
10$:	BLSCAL	BL$MOV,<GEN.1S,#RCVBUF,#GEN.1D> ; Move the text
	CLR	R0			; Return a zero to top level
99$:	RTS	PC			; Return to caller.
	.SBTTL	INPUT2 - Input two lines of text

;++
; This routine will input two lines of text from the user.  The text will
; be stored in the generic command argument blocks along with the length.
;
; Usage:
;
;	BLSCAL	INPUT,Flag,Header,Header.lenght,Text,Prompt,Prompt2
;
; Flag - True/False to determine if a null field is allowed.
; Header - Address of the header text.
; Header.length - Number of bytes in the header
; Text - A single line of text to output
; Prompt - Prompt for the user
; Prompt2 - Second prompt for the user
;
;--

	.PSECT	$CODE$, RO, I

BLSRTN	INPUT2,5,<FLAG,HEADER,HDRLEN,TEXT,PROMPT,PRMPT2>
	JSR	PC,SETESC		; Allow escape sequences
	MOV	HEADER+2(SP),R0		; Get the header address
	MOV	HDRLEN+2(SP),R1		; And the length
	BLSCAL	PAINT,<R0,R1,#22.>,+	; Put box around prompt.
	BLSCAL	TT.TEXT,#INPHDR,+	; Output the header
	BLSCAL	TT.TEXT,2+..STKO+TEXT(SP),+ ; Output the other text
	BLSCAL	TT.OUTPUT,,-		; Output any remaining characters
	MOV	#M$PMT1,R0		; Get the address of the position string
	MOV	PROMPT+2(SP),R1		; Put address of first prompt in R1
	JSR	PC,BLDPMT		; Build the prompt

	MOV	FLAG+2(SP),R0		; Get the flag
	JSR	PC,DOINP		; Get the input

	TST	R0			; Continue with routine ?
	BNE	99$			; No, return to user.
;
; Here if we got something from the user
;
	MOV	IOSTAT+2,GEN.1S		; Move the length
	CMP	#MAX.MSG,IOSTAT+2	; Make sure this is small enough
	BGE	10$			; Too big, skip this
	MOV	#MAX.MSG,GEN.1S		; Move the size
10$:	BLSCAL	BL$MOV,<GEN.1S,#RCVBUF,#GEN.1D>,+ ; Move the text
	BLSCAL	TT.OUTPUT,,-		; Force it out

	MOV	#M$PMT2,R0		; Get the position string
	MOV	PRMPT2+2(SP),R1		; Get address of second prompt.
	JSR	PC,BLDPMT		; Build the prompt string

	MOV	FLAG+2(SP),R0		; Get the flags again
	ASR	R0			; Shift so we just get the other one
	JSR	PC,DOINP		; Get the other string
	TST	R0			; Stay with routine ?
	BNE	99$			; No, return to user.
;
; Here if we got the second argument
;
	MOV	IOSTAT+2,GEN.2S		; Move the length
	CMP	#MAX.MSG,IOSTAT+2	; Make sure this is small enough
	BGE	20$			; Too big, skip this
	MOV	#MAX.MSG,GEN.2S		; Move the size
20$:	BLSCAL	BL$MOV,<GEN.2S,#RCVBUF,#GEN.2D> ; Move the text
	CLR	R0			; Clear so we do the right thing
99$:	RTS	PC			; Return to the caller
	.SBTTL	BLDPMT - Build the prompt string

;++
; This routine will build the prompt string.
;
; Usage:
;	MOV	Pos.text.addr,R0
;	MOV	Prompt.text.addr,R1
;	JSR	PC,BLDPMT
;	(Return)
;
; On return:
;	R1 - Address of the prompt
;	R2 - Length of the text
;--

	.PSECT	$CODE$, RO, I

BLDPMT:	MOV	#BUFF1,R2		; Address to store it
10$:	MOVB	(R0)+,(R2)+		; Store a byte
	BNE	10$			; Loop until finished
;
; Here if the prompt is copied
;
	TSTB	-(R2)			; Back up the poniter
20$:	MOVB	(R1)+,(R2)+		; Store the next byte
	BNE	20$			; Loop for all of these too
	SUB	#BUFF1+1,R2		; Calculate the number of bytes
	MOV	#BUFF1,R1		; Point to the buffer
	RTS	PC			; Return to the caller
	.SBTTL	DOINP - Read a line of text from the user

;++
; This routine will read a line of text from the user's terminal.
;
; Usage:
;	MOV	Flag,R0			- Save the flag
;	MOV	PROMPT.ADDRESS,R1	- Address of prompt into R1
;	MOV	PROMPT.LENGTH,R2	- Length of prompt into R2
;	JSR	PC,DOINP
;	(Return)
;
;--

	.PSECT	$CODE$, RO, I

DOINP::	QIOW$S	#IO.RPR!TF.BIN,#TERLUN,#TTREFN,,#IOSTAT,,<#RCVBUF,#100.,,R1,R2>
	TST	R0			; Is no input valid ?
	BEQ	20$			; Yes, branch.
	TST	IOSTAT+2		; Did we get any characters ?
	BNE	20$			; Yes, branch.
	BLSCAL	TT.TEXT,#NOINP		; Queue up the error message.
	BLSCAL	TT.OUTPUT		; Output it.
	BR	DOINP			; Try again.
;
; Here if we got an input file name.
;
20$:	MOV	R0,-(SP)		; Save the flag value.
	JSR	PC,CHKEXT		; Check what we got.
	CMP	#1,R0			; Was it a bad function key ?
	BNE	30$			; No, continue.
	MOV	(SP)+,R0		; Resore the flag value.
	BR	DOINP			; Try again.
;
; If here then we got a good input file name.
;
30$:	MOV	IOSTA1,R1		; Get the number of characters input
	CLRB	RCVBUF(R1)		; Clear the last byte
	TST	(SP)+			; Remove the item from the stack
	RTS	PC			; Return to caller.
	.SBTTL	Exit Check for Rcvfile


CHKEXT:	CLR	R0			; Give a good return
	MOV	IOSTAT+2,R2		; Get the count of characters
	BEQ	99$			; Just return if nothing
	MOV	#RCVBUF,R1		; Put address of input buffer into R1.

10$:	CMPB	#.CHESC,(R1)+		; Is the character an "ESCAPE" ?
	BEQ	20$			; Yes, branch.
	SOB	R2,10$			; Decrement the character count
	RTS	PC			; Just return if no escape
;
; Here if we have an <Escape>
;
20$:	DEC	R2			; Decrement the count of characters
	BLT	99$			; Branch if no more characters
	CMPB	#'[,(R1)+		; Was the next character a "[" ?
	BNE	105$			; No, branch.
	DEC	R2			; Decrement the count of characters
	BLT	99$			; Branch if no more characters
	CMPB	#'2,(R1)+		; Was the next a "2" ?
	BNE	105$			; No, branch.
	CMPB	#'0,(R1)		; Was the next a "0" ? ( MAIN SCREEN )
	BEQ	90$			; Yes, branch.
	DEC	R2			; Decrement the count of characters
	BLT	99$			; Branch if no more characters
	CMPB	#'1,(R1)+		; Or was that one a "1" ? ( EXIT )
	BNE	105$			; Neither then branch.

90$:	MOV	#2,R0			; Set up an EXIT return.
99$:	RTS	PC			; Return to caller.

105$:	BLSCAL	TT.TEXT,#WRONGKEY	; Output the text
	BLSCAL	TT.OUTPUT		; Output any remaining characters
	MOV	#1,R0			; Set up a WRONG FUNCTION KEY return.
	RTS	PC			; Return to the caller
	.SBTTL	SETESC - Allow escape sequences on this command

;++
; This will allow escape sequences on the following QIOs.
;
; Usage:
;	JSR	PC,SETESC
;	(Call back)
;
; On return:
;	This routine is stack to return to, so we can disallow escape
;	escape sequences.
;--

	.PSECT	$PLIT$, RO, D

IOLOC:	.BYTE	TC.ESQ,1		; Recognize escape sequences

	.PSECT	$CODE$, RO, I

	.GLOBL	SETESC

SETESC::
	QIOW$C	SF.SMC,TERLUN,5,,IOSTAT,,<IOLOC,2.>,$CODE$
	QIOW$C	IO.ATT!TF.ESQ,TERLUN,TTAEFN,,IOSTAT,,,$CODE$
	JSR	PC,@(SP)+		; Call the caller back
	QIOW$C	IO.DET,TERLUN,TTAEFN,,IOSTAT,,,$CODE$
	RTS	PC			; Return to the caller
	.SBTTL	Convert from ascii to binary

;++
;	INPUT:	R2	Address of buffer with ascii
;		R5	Original base of number
;
;	OUTPUT:	R1	Contains binary value
;
;	REGISTERS used:	R0, R1, R2, R5
;		R0	Temporary value location (destroyed)
;		R1	(value returned)
;		R2	(destroyed)
;		R5	(preserved)
;

ASCBIN::CLR	R1			; Clear out result location
10$:	MOVB	(R2)+,R0		; Get first digit
	BEQ	99$			; Check for end
	SUB	#'0,R0			; Get binary value of digit
	CLC				; Clear the carry for the mult.
	MUL	R5,R1			; Shift the rest of the answer over 
					;   one place (multiply by base)
	ADD	R0,R1			; Add in last digit
	BR	10$			; Loop for all digits

99$:	RTS	PC			; Return to sender
;
; This routine checks to see if input values are legal for the base specified
;
;	INPUT:	R2	Address of buffer with ascii
;		R5	Original base of number
;
;	OUTPUT:	Carry set if bad character was found.
;
;	REGISTERS used:	R0, R2, R5
;		R0	temporary value holder (destroyed)
;		R2	(destroyed)
;		R5	(preserved)
;

BASCHK::
	MOVB	(R2)+,R0		; Get first digit
	CLC				; Clear carry
	BEQ	99$			; Check for end
	SUB	#'0,R0			; Convert to binary digit
	BMI	90$			; If less then ascii zero then bad
	SUB	R5,R0			; Subtract base value
	BPL	90$			; If greater than or equal to the 
					;   ascii of base then bad
	BR	BASCHK			; Loop for the rest
90$:	SEC				; Set carry since bad character found
99$:	RTS	PC			; Return to sender
	.SBTTL	SNDPKT - Send the function to KERFIL and wait until it finishes

;++
; This routine will send a function to the KERFIL task and then wait until
; it completes the operation that we requested.
;
; Usage:
;	R0 - Function to send
;	JSR	PC,SNDPKT
;	(Return)
;
; On return:
;	Function completed, KERFIL still active, or KERFIL dead
;--

	.PSECT	$CODE$, RO, I

	.GLOBL	SNDPKT

SNDPKT:	JSR	PC,IT$SND		; Send the information to the other end
;
; Now wait until we get the response from the other end.
;
	WTSE$S	#ITCEFN			; Wait until we are told to go again
	CLEF$S	#ITCEFN			; Clear the event flag
	JSR	PC,IT$RDA		; Get the data
;
	RTS	PC			; Return to sender
	.SBTTL	Error routines

;
; Error routine for the ReQueSt task directive (starts KERFIL)
;
;	INPUT:	None
;
;	OUTPUT:	The request task error message is displayed and a fatal error
;		is given.  Control returns to P/OS Main menu

RQSERR:	MOV	#ERRRQS,ADRERR		; Get the error message to be printed
	MOV	#8.,BASE		; Set up for octal conversion
	JMP	ERROR			; call the main error routine
	.SBTTL	Generic command processing - CLRGEN - Clear generic arguments

; This routine will clear the generic command arguments so that KERMSG
;will not think there is something there.
;
; Usage:
;	JSR	PC,CLRGEN
;	(return here, all registers intact)
;

CLRGEN::CLR	GEN.1SIZE		; No first argument
	CLRB	GEN.1DATA		; In case someone thinks its ASCIZ
	CLR	GEN.2SIZE		; No second argument
	CLRB	GEN.2DATA		; In case someone thinks its ASCIZ
	CLR	GEN.3SIZE		; No third argument
	CLRB	GEN.3DATA		; In case someone thinks its ASCIZ
	RTS	PC
	.SBTTL	DEFINI - Initlialize the default file processing

;++
; This routine will determine if the default file contains the
; default parameters for the XK port.  It will then read them into the
; common area if they are in the file.  If they are not it will read
; the current parameters into the default area.
;--

	XK.IDX==	"XK			; Index to XK parameters

	.PSECT	$CODE$,	RO

DEFINI:	JSR	PC,DF.INI		; Initialize the default file
	MOV	#XK.IDX,R0		; Get the record to read
	JSR	PC,DF.RD		; Read the record
	TST	R1			; Did we read anything?
	BGT	10$			; Yes, skip this

; Here if there were no parameters in the file, so just use what
; the port is currently set at as the parameters and some other things
; that we must default.

	JSR	PC,XK.INT		; Initialize the XK port

	BLSCAL	BL$MOV,<#CURXKL,#ORGXKP,#CURXKP> ; Move the parameters
;
; Now make some parameters consistant
;
	MOV	#TC.PAR,R0		; Get the parity setting
	MOV	#CURXKP,R1		; From this block
	JSR	PC,FNDXKP		; Find the parameter
	TST	R0			; Find it?
	BEQ	4$			; No, skip this (should be there)
	CLRB	@R0			; Clear to turn off parity
;
; Here to set the data character size
;
4$:	MOV	#TC.FSZ,R0		; Get the data size
	JSR	PC,FNDXKP		; Find the parameter
	TST	R0			; Did we find it?
	BEQ	6$			; Branch if not
	MOVB	#8.,@R0			; Set to 8 bit characters
;
; Now write the defaults
;
6$:	MOV	#XK.IDX,R0		; Index for the file
	MOV	#CURXKP,R1		; Address of the parameters
	MOV	#CURXKL,R2		; Length of the block
	JSR	PC,DF.WT		; Write the parameters
;
; Now to shut down the port, since we don't need it
;
	JSR	PC,XK.SHT		; Shut down the XK again
	BR	30$			; Copy over to the default area

; Here if we have parameters in the default file for the XK port.
; Just copy the parameters to the correct area, so we can use them
; later.

10$:	CMP	#CURXKL,R1		; Have enough area?
	BEQ	20$			; Long enough area
	MOV	#CURXKL,R1		; No, use this length

20$:	BLSCAL	BL$MOV,<R1,R0,#CURXKP>	; Move the parameters
;
; Now copy the parameters to the default area
;
30$:	BLSCAL	BL$MOV,<#CURXKL,#CURXKP,#DEFXKP>
;
; Close the parameter file now.
;
	JSR	PC,DF.FIN		; Finished with this for now
	RTS	PC			; Return to the caller
	.SBTTL	End of KERMIT


	.END	FROG			; That's all folks! (Ribbit)
