;CBBS	O O	  O	O O	.ASM
;	O   O	  O	O
;	O O	  O	O O O
;
;	ALSO CONTAINS THE HELP COMMAND
;
;WRITES COMMENTS TO THE LOG FILE.  EACH IS
;PRECEEDED WITH A ']' SUCH THAT IN OPERATOR MODE,
;'TYPE LOG' COMMAND WILL ACCEPT CTL-C TO SKIP
;TO THE NEXT LOG ENTRY
;
;MODS (THRU 3.2 WRITTEN TO "HISTORY")
;
;====> HISTORICAL COMMENTS SINCE 3.3 TO "HISTORY.033"
;
;	----------------
BYE	LDA	COMFLG	;GET FLAG
	CPI	'B'	;IF BUSY THEN DON'T..
	JZ	BYEBYE	;..TRY WRITING COMMENT
	LXI	H,' 1'
	SHLD	COMLNO	;INIT COMMENT LINE COUNTER
;
	IF	TWITCK
	CALL	TWITST
	MVI	A,1	;TO ZAP CTL-K FUNCT
	JZ	BYENCK
	LDA	TWITSW
	ORA	A
	JNZ	BYENCK
;
	ENDIF
;
	MVI	A,'B'	;SET..
	STA	COMFLG	;..BUSY
	JMP	BYEASK
BYEYN:
;
	IF	HAYES
	IN	DCHST	;CHECK FOR CARRIER LOSS
	ANI	DCHCD
	ENDIF
;
	IF	IDS
	IN	IDSST
	ANI	IDSCTS	;CLEAR TO SEND? (=CARRIER LOSS)
	ENDIF
;
	IF	PMMI
	IN	PMMIMST
	CMA		;PMMI = NOT(CTS)
	ANI	PMMICTS
	ENDIF
;
	JZ	BYEBYE	;TREAT AS IF 'N' WERE ENTERED
	CALL	ILPRT
	DB	'Please answer Yes or No',CR,LF,0
BYEASK	LDA	PASSFLG	;OPER?
	ORA	A
	JZ	CMOP1
	LDA	CLEFT
	ORA	A
	JZ	BYEBYE
CMOP1:
	CALL	GETVAR
	DB	'Comments Y/N: Want to leave any '
	DB	'comments or suggestions '
	DB	CR,LF,0
	DW	ANSWER
	DW	5	;HELP MSG #
	DB	9
	LDA	ANSWER
	CPI	'-'
	JZ	FUNCT
	CPI	CR	;JUST C/R?
	JZ	BYEYN	;YES, RE-ASK
;IF NO, CLOSE FILE LEAVING JUST NAME.
	CPI	'N'	;NO?
;
	IF	CLOCK
	STA	BYEFLG
	JZ	BYETIME
	ENDIF
;
	IF	NOT CLOCK
	JZ	BYEBYE	;NO COMMENTS
	ENDIF
;
	CPI	'Y'	;YES?
	JNZ	BYEYN	;NOT 'YES' - REASK
;
;DISABLE CTL-K TEST WHILE WRITING COMMENT FILE
;
BYETIME	MVI	A,1
	STA	CTLKSW
	STA	DKUPSW	;SHOW UPDATING DISK
	LXI	H,LOGFL	;POINT TO FILENAME
	CALL	EXTEND	;EXTEND THE LOG FILE
;
	IF	CLOCK
	CALL	WRETIME	;WRITE ELAPSED TIME
;	CALL	WRCRLF
;
;IF 'NO' COMMENTS REQUESTED, JUST CLOSE FILE
;
	LDA	BYEFLG
	CPI	'N'
	JZ	COMEND
	ENDIF		;CLOCK
;
	CALL	WRCRLF
	MVI	A,']'	;ALLOW CTL-C SKIP TO
	CALL	WRBYTE	;..NEXT COMMENT
	LDA	EXPERT
	ORA	A
	JNZ	COMLP	;SKIP INSTR FOR EXPERIENCED USER
	CALL	ILPRT
	DB	CR,LF
	DB	CR,LF
	DB	'Enter your comments.  Use ctl-U '
	DB	'for line cancel,'
	DB	CR,LF
	DB	'and DEL or CTL-H '
	DB	'for backspacing.',CR,LF
	DB	'Each line may be up to 60 chars long.'
	DB	CR,LF,0
	LDA	BELLF
	ANI	1
	JZ	COMENT
	CALL	ILPRT
	DB	'(Bell sounds after 55)'
	DB	CR,LF,0
;
COMENT	CALL	ILPRT
	DB	'Enter each line, '
	DB	'press return twice to end',CR,LF,0
COMLP	CALL	GETVAR
COMLNO	DB	' 1:',0
	DW	ANSWER
	DW	6	;HELP MSG #
	DB	60
	LDA	ANSWER
	CPI	CR
	JZ	COMEOI
;START OF MODS TO SEE IF "HELP" ENTERED
	LXI	D,ANSWER
	LXI	H,HELPFL+1	;TO "HELP"
	CALL	COMP4		;SEE IF "HELP"
	JNZ	BYNHELP
	LDA	ANSWER+4
	CPI	CR
	JNZ	BYNHELP
	CALL	ILPRT
	DB	'Continue typing your comments to the '
	DB	'CBBS operators.',CR,LF,0
	JMP	COMENT
;
;START OF MODS TO LIMIT # OF COMMENT LINES
;
BYNHELP	LDA	CLEFT
	DCR	A
	STA	CLEFT
	CPI	4
	CC	CMPRNL	;PRT # LEFT
;SOMETHING WAS ENTERED - WRITE IT OUT
	LXI	H,ANSWER
	CALL	WRLINE
	LDA	PASSFLG	;OPER?
	ORA	A
	JZ	CMOP
	LDA	CLEFT
	ORA	A
	JZ	COMWRN	;ALL DONE, CLOSE UP
;
CMOP	LDA	INBUF
	CPI	CR
	JNZ	COMLP	;HAVE STACKED ANSWER
	LXI	H,COMLNO+1
	CALL	ADD1
	JMP	COMLP
;
CMPRNL	ADI	'0'
	CALL	TYPE
	CALL	ILPRT
	DB	' lines left',CR,LF,0
	RET
;
;C/R ENTERED, BE SURE THEY ARE DONE
;
COMEOI	CALL	GETVAR
	DB	'Y/N Done',0
	DW	ANSWER
	DW	0	;HELP MSG #
	DB	6
	LDA	ANSWER
	CPI	'N'
	JZ	COMLP
	CPI	CR
	JZ	COMWRN	;IF C/R, LET THEM GO
	CPI	'Y'
	JNZ	COMEOI
;
;END OF COMMENT, WRITE NAME
;
COMWRN	CALL	WRNAME	;"FN LN,"
;	CALL	WRCRLF	;NEXT CALLER WILL CR/LF
;
;CLOSE OUT COMMENTS FILE
;
COMEND	CALL	WREOF	;WRITE EOF, CLOSE FILE
BYEBYE	XRA	A	;ENABLE THE
	STA	DKUPSW	;SHOW NO LONGER UPDATING DISK
;ADD FOLLOWING XRA A
BYECTLK	XRA	A
BYENCK	STA	CTLKSW	;..CONTROL-K TEST
	MVI	A,'N'	;RESET COMMENT BUSY FLAG
	STA	COMFLG
	LXI	H,BYMSG	;GET GOOD BYE MESSAGE
	CALL	TYPEM0	;TYPE THE MESSAGE
	LXI	H,FNAME	;POINT TO FIRST NAME
	CALL	TYPEMCR
	CALL	CRLF
;
	IF	CLOCK
	LDA	BYEFLG
	CPI	'N'	;NO COMMENTS?
	CNZ	PRETIME	;ELAPSED TIME
	ENDIF
;
;
	IF	TTY
	MVI	A,80
	STA	COL	;FAKE UP TO CAUSE C/R
	MVI	A,CR
	CALL	LOG	;LOG A C/R
;GIVE ABOUT 8 SEC FOR LOG TTY TO COMPLETE
	LXI	H,4000H
ENDTTY	PUSH	H
	CALL	CKTTY
	POP	H
	DCX	H
	MOV	A,H
	ORA	L
	JNZ	ENDTTY
	ENDIF
;
	LXI	H,HUNGUP
	JMP	PRDIS	;PRINT MSG, DISCONNECT, EXIT
HUNGUP	DB	CR,LF
	DB	'++End of connection++',CR,LF
	DB	LF,LF,LF,0
;
BYECR	CALL	KEYCHR	;GET A CHAR
	JZ	BYECR
	CPI	CR
	JNZ	BYECR
BYECR2	CALL	KEYCHR
	JZ	BYECR2
	CPI	CR
	JNZ	BYECR
	MVI	A,CR	;DELETE FIRST NAME
	STA	FNAME
	JMP	START
;
;-----> HELP FUNCTION - INTERPRET QUESTIONS IN 'HELP' FILE
;
HELP	MVI	A,1
	STA	INHELP		;FORCE "X" THRU AS KEYWORD
	CALL	GETVAR
	DB	CR,LF
	DB	'Keyword: Enter a single word '
	DB	'which best ',CR,LF
	DB	'describes the function you '
	DB	'want help on. ',CR,LF
	DB	'Type ? to list all '
	DB	'keywords.',CR,LF
	DB	'Type ?? to list keywords and '
	DB	'a BRIEF explanation',CR,LF
	DB	0
	DW	ANSWER
	DW	-1	;HELP MSG # (NONE, PASS "?" BACK)
	DB	20
HELP2	LDA	ANSWER
	CPI	CR
	JZ	FUNCT
	LDA	ANSWER
	CPI	'?'
	JZ	HWORDS
	LXI	H,HELPIDX ;TRY OPENING INDEX
	CALL	SETRD
	JC	HSCAN	;NO INDEX, SCAN THE HELP FILE
;
;LOOK UP WORD IN INDEX
;
HXLOOP	CALL	CTLCKS	;ALLOW ^K
	CALL	RDBYTE
	JC	HLPNW
	CPI	LF
	JNZ	HXLOOP
	LXI	H,ANSWER-1
HXMATCH	CALL	RDBYTE
	JC	HLPNW
	INX	H
	CMP	M
	JZ	HXMATCH
	CPI	','	;END OF WORD?
	JNZ	HXLOOP	;NOPE, TRY AGAIN
	MOV	A,M	;GET KEYWORD
	CPI	CR	;END?
	JNZ	HXLOOP	;NOPE, NOT IT
;
;FOUND THE WORD IN THE INDEX - USE IT TO SET
;	UP THE FCB
;
	CALL	DKRDHEX	;GET EXTENT
	PUSH	PSW	;SAVE IT
	CALL	DKRDHEX	;GET HEX DIGIT
	ADD A ! ADD A ! ADD A ! ADD A ;X16
	MOV	B,A
	PUSH	B
	CALL	DKRDHEX	;GET SECOND DIGIT
	POP	B
	ADD	B
	MOV	B,A	;SAVE REC #
	POP	PSW	;GET EXTENT
	PUSH	B	;SAVE REC #
	STA	FCBEXT
	LDA	HELPFL	;GET DISK
	STA	FCB	;SET DISK
	MVI	A,' '
	STA	FCB+9	;MAKE HELP.IDX
	STA	FCB+10	;	INTO
	STA	FCB+11	;	HELP
	CALL	SETOPEN
	JC	HELPNF
	POP	B	;RESTORE REC #
	MOV	A,B	;GET REC #
	STA	FCBRNO
	JMP	HMLOOP
;
HSCAN	LXI	H,HELPFL
	CALL	SETRD
	JC	HELPNF
;
;KEYWORD ENTERED, TRY TO FIND IT
;
HMLOOP	CALL	CTLCKS	;ALLOW ^K
	CALL	RDBYTE
	JC	HLPNW
	CPI	'['	;START OF WORD?
	JNZ	HMLOOP
	LXI	H,ANSWER-1
HMMATCH	CALL	RDBYTE
	JC	HLPNW
	INX	H
	CMP	M
	JZ	HMMATCH
	CPI	'='	;END OF WORD?
	JNZ	HMLOOP	;NOPE, TRY AGAIN
	MOV	A,M	;GET KEYWORD
	CPI	CR	;END?
	JNZ	HMLOOP	;NOPE, NOT IT
;
;GOT KEYWORD IN FILE, TYPE DESCRIPTION
;
	CALL	ILPRT
	DB	'Use CTL-K to abort HELP'
	DB	CR,LF,0
;
HLPTYPE	CALL	RDBYTE
	JC	HLPMORE
	CPI	']'
	JZ	HLPMORE
	CPI	'['	;SYNONYM LINE?
	JNZ	HLPT2
;
;SKIP A SYNONYM EXPLANATION
;
HLPSKS	CALL	RDBYTE
	JC	HLPMORE
	CPI	LF
	JNZ	HLPSKS
	JMP	HLPTYPE
;
HLPT2	CALL	TYPE
	CALL	CTLCKS	;ALLOW ABORT
	JZ	HLPMORE	;CTL-C TYPED
	JMP	HLPTYPE
;
;KEYWORD ASKED FOR NOT IN HELP FILE
;
HLPNW	EQU	$
	LXI	H,LOGFL	;POINT TO FILENAME
	CALL	EXTEND	;EXTEND THE LOG FILE
	CALL	WRCRLF
	LXI	H,HELPHDR
	CALL	WRVAR	;WRITE "]HELP: "
	LXI	H,ANSWER
HLPWC	MOV	A,M
	INX	H
	CPI	CR
	JZ	HLPWE
	CALL	WRBYTE
	JMP	HLPWC
;
HLPWE	MVI	A,','
	CALL	WRBYTE
	CALL	WREOF	;CLOSE FILE
	CALL	ILPRT
	DB	'Keyword not in help file'
	DB	CR,LF,0
;
;ASK IF ANOTHER WORD IS WANTED
;
HLPMORE	CALL	GETVAR
	DB	CR,LF
	DB	'Next keyword: (or press return '
	DB	'to end HELP)',0
	DW	ANSWER
	DW	7	;HELP MSG #
	DB	20
	JMP	HELP2
;
HELPHDR	DB	']HELP: ',CR
;
;'?' OR '??': TYPE ALL KEYWORDS IN THE HELP FILE
;
HWORDS	LXI	H,HELPFL
	CALL	SETRD
	JC	HELPNF
	CALL	ILPRT
	DB	'Use K or ctl-K to abort',CR,LF,0
HWNXT	CALL	RDBYTE
	JC	HELP
	CPI	'['	;START OF WORD?
	JNZ	HWNXT
HWLP	CALL	RDBYTE
	JC	HELP
	CPI	CR
	JZ	HWEND
	CPI	'='
	JNZ	HWTYPE
	LDA	ANSWER+1	
	CPI	'?'	;'??' TYPED?
	JNZ	HWENDW
	MVI	A,'='
HWTYPE	CALL	TYPE
	CALL	CTLCKS	;ABORT?
	JMP	HWLP
;
HWEND	CALL	CRLF
	JMP	HWNXT
;
;END OF WORD, C/R IF COL>=49
;
HWENDW	LDA	TABCOL
	CPI	49
	JNC	HWEND
	MVI	A,TAB
	CALL	TYPE
	LDA	TABCOL
	ANI	0FH
	MVI	A,TAB
	CNZ	TYPE
	JMP	HWNXT
;
HELPNF	CALL	ILPRT
	DB	'++Sorry, no HELP file on disk!++',cr,lf,0
	jmp	funct
;	RZ
;	CPI	'['
;	RZ
;	CPI	7
;	RET
;
;====>	SYNTAX ERROR IN HELP FILE
;
IQSNERR	CALL	ILPRT
	DB	'Sorry, help file error',cr,lf,0 ;OT TO NAME
	CALL	INTQF	;INTERPRET QUESTION FILE
	JMP	FUNCT
;
;================================================
;
;====>	INTQF	ROUTINE TO INTERPRET QUESTION FILE
;
;	FILE FORMAT FOR QUESTION IS:
;
;[THIS IS THE QUESTION
;THIS IS THE ANSWER
;(AS MANY LINES AS REQUIRED)
;] 	<----SIGNIFIES END OF QUESTION
;
;	NOTE:  a ";" following a "]" makes the
;	rest of the line a comment.
;	A "Q" following a "]" means Quit right now.
;
;Example: (Of course no ';' are in the
;actual question file at the start of lines)
;
;[Want to know what control-C does
;Control-c suppresses output to your
;terminal until the next input is
;asked for.
;]Q
;[Want help with such-and-such
;blah - blah - blah
;];this is a comment
;
;NESTED QUESTIONS ARE HANDLED, TOO: IF NO
;IS ANSWERED TO AN OUTER QUESTION,  THEN
;INNER NESTED QUESTIONS ARE SKIPPED.
;
INTQF	CALL	SETRD	;SET UP FILE
	RC		;RET IF ERROR
;
;TYPE THE PROLOG, OR LINES BETWEEN QUESTION.
;	^C TAKES USER TO FIRST QUESTION
;
IQPRO	CALL	IQTYPE	;TYPE WORDS BETWEEN QUESTIONS
	RC		;	RETURN ON EOF
	CPI	'['	;M-U-S-T BE A QUESTION
	JNZ	IQSNERR	;	OTHERWISE SYNTAX ERR
	CALL	IQUEST	;HANDLE A QUESTION,
	RC		;	RETURN ON EOF OR QUIT
	JMP	IQPRO	;LOOP
;
;RECURSIVE CALL TO IQUEST:
;
IQUESTR	CALL	IQUEST	;HANDLE QUESTION
	RC		;EOF OR QUIT?
	JMP	IQUEST2	;CONTINUE WITH (POSS) TEXT
;
;====>	IQUEST	ASKS A QUESTION
;
;	NOTE THIS IS A RECURSIVELY-CALLABLE SUBROUTINE
;
IQUEST	CALL	IQTYPEQ	;TYPE THE QUESTION
	CALL	IQANS	;ASK Y/N
	RC		;CARRY MEANS QUIT
	CPI	'N'	;NO?
	JZ	IQSKIP	;	SKIP Q AND NESTED Q'S
IQUEST2	CALL	IQTYPE	;YES? TYPE THE ANSWER
	RC		;IF EOF
	CPI	'['	;NESTED QUESTION?
	JZ	IQUESTR	;YES, HANDLE IT RECURSIVELY
;
;GOT END OF QUESTION - CHECK FOR SPECIAL ACTIONS:
;
;	X....	EXECUTE COMMAND
;	Q	QUIT OUT OF HELP
;	;	REST OF LINE IS COMMENT
;
	CALL	RDBYTE	;GET OPTION
	RC		;EOF
	CPI	';'	;COMMENT?
	JZ	IQSKLF	;	YES, SKIP IT
	ANI	5FH	;MAKE UPPER CASE
	CPI	'Q'
	STC
	RZ		;FAKE UP EOF IF QUIT
	LXI	H,INBUF	;SET UP FOR 'X'
	CPI	'X'	;EXECUTE?
	JZ	IQX	;	YES, DO IT
;
;NO SPECIAL REQUEST.  PUT IT BACK
;
	CALL	UNRDBYT
	ORA	A	;NO CARRY = NO EOF
	RET
;
;====>	IQTYPEQ	TYPE THE QUESTION
;
IQTYPEQ	CALL	RDBYTE
	RC
	CPI	CR	;IF CR, SKIP TO LF,
	JZ	IQSKLF	;	THEN RETURN
	CALL	TYPE
	CALL	CTLCKS	;IF NOT ^C,
	JNZ	IQTYPEQ	;	LOOP
	CALL	CRLF	;ELSE, CRLF
	JMP	IQSKLF	;	THEN SKIP REST
;
;====>	IQANS	GETS Y/N/Q ANSWER
;
IQANS	LDA	INBUF	;STACKED ANSWER?
	CPI	CR	;EMPTY BUFFER?
	CNZ	CRLF	;	NO, CRLF
	CALL	GETVAR	;GET THE ANSWER
	DB	0	;NO MESSAGE
	DW	ANSWER	;READ IN HERE
	DW	0	;HELP MSG #
	DB	9	;MAX LEN
	LDA	ANSWER
	CPI	'Y'	;YES?
	RZ		;	"YES", SO RETURN
	CPI	'N'	;NO?
	RZ		;	"NO", SO RETURN
	CPI	'Q'	;REQUEST TO
	STC		;FAKE UP AS EOF
	RZ		;	QUIT OUT
	MVI	A,CR	;PURGE INBUF
	STA	INBUF	;	OF BUFFERED ANSWERS
	CALL	ILPRT
	DB	'Y/N/Q, Please: answer Yes or No, or Quit',0
	JMP	IQANS
;
;SKIP A "NO" ANSWER AND ASSOCIATED NESTED ANSWERS
;
IQSKIP	CALL	CTLCKS	;ALLOW ^K, BUT IGNORE ^C
	CALL	IQDSKIP	;SKIP TO NEXT DELIMITER
	RC
	CPI	7	;BELL HDR FOR TYPING MSGS?
	RZ
	CPI	'['	;NESTED Q.?
	CZ	IQSKIP	;YES, SKIP IT, TOO
	CPI	']'	;END?
	JNZ	IQSKIP	;LOOP UNTIL @ END
;
;GOT END OF "NO" ANSWER.
;	SKIP Q, X, OR COMMENTS
;
IQSKP2	CALL	RDBYTE	;GET NEXT BYTE
	RC
	CPI	';'	;COMMENT?
	JZ	IQSKLF
	ANI	5FH	;MAKE UPPER CASE
	CPI	'Q'
	JZ	IQSKLF	;IGNORE 'Q' LINE
	CPI	'X'	;FUNCTION TO EXECUTE?
	JZ	IQSKLF	;TREAT LIKE COMMENT
	CALL	UNRDBYT	;PUT IT BACK
	ORA	A	;NOT EOF
	RET
;
;====>	IQX:	EXECUTE A COMMAND
;
IQX	CALL	RDBYTE
	JC	DEFUNCT	;PREMATURE EOF
	MOV	M,A
	CALL	TYPE
	MOV	A,M
	INX	H
	CPI	CR
	JNZ	IQX
	CALL	CRLF
	JMP	FUNCT	;EXECUTE STACKED COMMAND
;
;====>	IQTYPE	TYPES TEXT UP TO NEXT [ OR ]
;		^C SKIPS
;
IQTYPE	CALL	IQRDTST	;READ, TEST FOR DELIM
	RC
	RZ		;RET IF DELIM
	CALL	TYPE
	CALL	CTLCKS	;ALLOW ^C, ^K
	JNZ	IQTYPE
	CALL	CRLF
;
;====>	IQDSKIP	SKIP TO NEXT DELIMITER
;
IQDSKIP	CALL	IQRDTST	;READ, TEST FOR DELIM
	RC
	RZ
	JMP	IQDSKIP
;
;====>	IQRDTST	READ, TEST FOR DELIM
;		RETURNS Z ON DELIM
IQRDTST	CALL	RDBYTE
	RC
	CPI	']'
	RZ
	CPI	'['
	RZ
	CPI	7
	RET
;
;====>	SYNTAX ERROR IN HELP FILE
;
IQSERR	CALL	ILPRT
	DB	'Sorry, help file error!!',CR,LF,0
	STC
	RET
;
;====>	IQSKLF	SKIPS A LINE, THRU THE L/F
;
IQSKLF	CALL	RDBYTE	;SKIP TO LF WHETHER
	RC		;IN CASE EOF
	CPI	LF	;	OR NOT CTL-C
	JNZ	IQSKLF	;WAS TYPED DURING QUESTION
	RET
;
	LINK	CBBSSUMM ;TO NEXT .ASM FILE
