;CBBS V3.5.0	CBBSFUNC.ASM - MAINLINE PART 2
;11/21/81 12:45:36
;	LINKS TO CBBSBYE
;
;	O O O	O   O	O   O	O O O
;	O	O   O	OO  O	O
; CBBS	O O	O   O	O O O	O	.ASM
;	O	O   O	O  OO	O
;	O	O O O	O   O	O O O
;
;====> HISTORICAL COMMENTS SINCE 3.3 TO "HISTORY.033"
;
;	----------------
;GIVE BRIEF ASSISTANCE WITH COMMAND ABBREVIATIONS
;===>	(USED TO BE INLINE, NOW TYPES FROM FILE
;	"FUNCTION" TO ALLOW IT TO BE EASILY TAILORED)
;
ASIST	LXI	H,FUNCFL
	CALL	TYPEF
;	DB	CR,LF
;04;RE-ORDER THESE INTO MAJOR/MINOR
	DB	'----MAJOR FUNCTIONS SUPPORTED----',CR,LF
	DB	'E=Enter msg into system',CR,LF
	DB	'G=Good bye (leave system)',CR,LF
	DB	'H=KEYWORD HELP <===',CR,LF
	DB	'Q=Quick summary (Msg #, subject)',CR,LF
	DB	'R=Retrieve msgs by #',CR,LF
	DB	'S=Summary print/scan',CR,LF
	DB	CR,LF
	DB	'----MINOR FUNCTIONS SUPPORTED----',CR,LF
;	IF	IDS OR PMMI
;	DB	'A=Alter Baud rate',cr,lf
;	ENDIF
	DB	'B=Reprint bulletin',CR,LF
	DB	'C=Case switch (upper/lower)',CR,LF
	DB	'D=Duplex switch (echo/no echo)',CR,LF
	DB	'K=Kill msg from system',CR,LF
	DB	'N=Nulls: Set as many as req''d',CR,LF
;	DB	'P=Prompt switch (BELL on/off)',CR,LF
;;
;	IF	CLOCK
;	DB	'T=Print date, time, elapsed time',CR,LF
;	ENDIF
;;
	DB	'V=Select Video backspace char',CR,LF
	DB	'W=Reprint welcome',CR,LF
01	DB	'X=Expert user mode',CR,LF
01	DB	'#=Print caller #, hi msg #, # msgs',CR,LF
;;
;06	DB	'NEWS=Print what''s new on CBBS',CR,LF
	DB	'HELP=New user help',CR,LF
;	DB	'SHORT=Suppress printing extra spaces',0
;
02 DEFUNCT MVI	A,CR	;KILL..
02	STA	INBUF	;..STACKED LINES
;
;---------------- MAIN ROUTINE ----------------
;
FUNCT	LXI	SP,STACK
	XRA	A	;GET 0
	STA	DKUPSW	;SHOW NO DISK UPDATE
	STA	CTLKSW	;ENABLE CTL-K
	STA	RTOGO	;KILL BLOCK RETRIEVE
	STA	STRFLG	;NO STRING MATCH IN FILE
06	STA	INHELP	;ALLOW "X" TO WORK
	LDA	PREVCHR	;IF PREV WAS C/R
	CPI	CR	;	THEN HAVE TO
	JZ	FUNCR	;	CR/LF
	LDA	TABCOL	;OTHERWISE, CRLF
	ORA	A	;	IF NOT IN
	JZ	FUNOCR	;	COLUMN 1
FUNCR	CALL	CRLF
FUNOCR	LHLD	FLAGPTR	;ANY FLAGGED
	MOV	A,H	;	MESSAGE
	ORA	A	;	TO RTRV?
	JNZ	RTRVFLG	; YES, DO IT
	CALL	GETVAR
	DB	'Function: '
;
	IF	PMMI OR IDS
	DB	'A,'	;ALTER BAUD RATE
	ENDIF
;
	DB	'B,C,D,E,G,H,K,N,Q,R,S,'
;
	IF	CLOCK
	DB	'T,'
	ENDIF
;
	DB	'V,W,X,# '
01	DB	CR,LF
01	DB	'(OR ? IF NOT KNOWN)',0
	DW	ANSWER	;READ INTO ANSWER
04	DW	-1	;HELP MSG #: PASS "HELP" AND "?"
04			;BACK TO THIS ROUTINE
	DB	40	;MAX ANSWER LEN
;
	LDA	ANSWER	;GET FIRST CHAR OF REPLY
	CPI	CR	;C/R ENTERED?
	JZ	FUNCT	;..YES, ASK AGAIN
;
	STA	SUMTYP	;REMEMBER "Q" OR "S"
	MOV	B,A	;SAVE CHAR
	LDA	ANSWER+1 ;SINGLE CHAR FNC?
	CPI	CR
	JNZ	SPEC	;CHECK FOR PASSWORD
	MOV	A,B	;GET FIRST CHAR
	CPI	'?'
	JZ	ASIST
;
	IF	PMMI OR IDS
	CPI	'A'
	JZ	ALTBAUD
	ENDIF
;
	CPI	'B'
	JZ	REBUL	;TYPE BULLETIN
	CPI	'C'
	JZ	CCASE	;CHANGE CASE
	CPI	'D'
	JZ	DUPLX	;FLIP/FLOP DUPLEX MODE
	CPI	'E'
	JZ	ENTER
	CPI	'G'
	JZ	BYE
	CPI	'H'
	JZ	HELP
;
	CPI	'K'
	JZ	KILL
;
	CPI	'N'
	JZ	CNUL
;	CPI	'P'	;CHG BELL PROMPT?
;	JZ	BELL
	CPI	'Q'
	JZ	SUMMRY	;QUICK SUMMARY
	CPI	'R'
	JZ	RTRV
	CPI	'S'
	JZ	SUMMRY
;
	IF	CLOCK
	CPI	'T'
	JZ	PRDTIME
	ENDIF
;
;
;====> "V" OBSOLETED 07/19/81
;
	CPI	'V'	;VIDBS NOW JUST
	JZ	VIDBS	;	SAYS "OBSOLETE"
;
	CPI	'W'
	JZ	REWEL
	CPI	'X'	;EXPERT USER?
	JZ	XPERT
01	CPI	'#'
	JZ	STATS
	JMP	WHATM	;INVALID FUNCTION
;
;CHECK FOR 4-BYTE FUNCTIONS.
;
SPEC	LXI	H,FTAB	;POINT TO FUNCTION TABLE
	CALL	CELOOK	;RET'S HL = FNC IF VALID
;
;NOT FOUND.  CHECK FOR OP FNC
;
	LDA	PASSFLG	;OPERATOR?
	ORA	A
	JZ	CEFNC	;PASSWORD HAS BEEN ENTERED
WHATM	LXI	H,WHAT	;GET 'DONT UNDERSTAND' MSG
	CALL	TYPEM0	;TYPE THE MESSAGE 
	LXI	H,ANSWER
	CALL	TYPEMCR
	LXI	H,QFNAME ;POINT TO ', (NAME)
	CALL	TYPEMCR
	CALL	CRLF
	JMP	DEFUNCT
;
;4-BYTE FUNCTION TABLE
;
FTAB	;DB	'HELP'
	;DW	HELPNEW	;NEW USER HELP
	DB	'SHOR'	;SHORT
	DW	SHORTEN
	DB	'NEWS'
	DW	NEWSCMD
	DB	'PASS'
	DW	GETPW
	DB	0

06;MODS
;
;====>	SHORT	COMMAND - ASKING FOR NO REDUNDANT
;		GRAPHIC CHARS, SPACE THRU "/"
SHORTEN	LDA	NONEFLG
	XRI	1
	STA	NONEFLG
	JZ	SHORTY
	CALL	ILPRT
	DB	'No ',0
SHORTY	CALL	ILPRT
	DB	'dup. chars.',CR,LF,0
	JMP	FUNCT
06;END
;
;SUBROUTINE TO ASK IF LOWER CASE CAN BE
;HANDLED.  (ASKED ONLY ONCE)
;
QCASE	LDA	CASE	;GET CASE
	INR	A	;WAS IT 0FFH (LOWER CASE OK)?
	RZ		;YES, RETURN
;HAVE WE ASKED?
	LDA	CASEFLG
	ORA	A
	RNZ		;YES, WE HAVE ASKED
	MVI	A,1	;SHOW WE HAVE ASKED
	STA	CASEFLG
;
	CALL	GETVAR
	DB	'LOWER CASE CHARACTERS, Y/N: '
	DB	'CAN YOUR TERMINAL HANDLE THEM',0
	DW	ANSWER
04	DW	3	;HELP MSG #
	DB	9
;
	LDA	ANSWER
	CPI	'N'
	RZ
	CPI	'Y'
	JNZ	QCASE
	MVI	A,0FFH	;LOWER CASE OK.
	STA	CASE
	RET
;
;CHANGE CASE BETWEEN UPPER AND LOWER
;
CCASE	LDA	CASE	;GET CASE MASK
	XRI	0A0H	;FLIP
	STA	CASE	;SAVE IT BACK
	LXI	H,LCASEM ;POINT TO 'lower/UPPER'
	INR	A	;WAS MASK 0FFH?
	JZ	LCASE2
	LXI	H,UCASEM ;POINT TO 'UPPER'
LCASE2	CALL	TYPEM0
	JMP	FUNCT
;
;SWITCH BETWEEN HALF AND FULL DUPLEX,
;I.E. ECHOING AND NOT ECHOING, BY TOGGLING
;THE ECHO FLAG
;
DUPLX	LDA	ECHOFLG
	INR	A
	ANI	1
	STA	ECHOFLG
	JNZ	FDX
	CALL	ILPRT
	DB	CR,LF,'Half duplex (no echo) mode'
	DB	CR,LF,0
	JMP	FUNCT
FDX	CALL	ILPRT
	DB	CR,LF,'Full duplex (echo) mode'
	DB	CR,LF,0
	JMP	FUNCT
;
;CHANGE NUMBER OF NULLS
;
CNUL	CALL	ILPRT
	DB	'Was: ',0
	LDA	NULLS
	CALL	PRDEC	;PRINT NNN
	LDA	INBUF	;ALREADY ANSWERED?
	CPI	CR
	CNZ	CRLF	;YES, CRLF
	CALL	GETVAR
	DB	': How many nulls ',0
	DW	ANSWER
04	DW	4	;HELP MSG #
	DB	3
	LDA	ANSWER
	CPI	CR
	JZ	FUNCT
	CALL	GETNUM	;GET BINARY #
	JC	CNUL	;INVALID, RE-ASK
	MOV	A,H
	ORA	A	;>255?
	JNZ	CNUL
	MOV	A,L	;GET VALUE (0-255)
	STA	NULLS
	CALL	CRLF
	JMP	FUNCT
;
;RETYPE THE WELCOME FILE
;
REWEL	LXI	H,WELCOM
	CALL	TYPEF
	JMP	FUNCT
;
;RETYPE THE BULLETIN FILE
;
REBUL	LXI	H,BULFL
	CALL	TYPEF
	JMP	FUNCT
06;MODS:
;
;TYPE THE NEWS FILE
;
NEWSCMD	CALL	GETVAR
	DB	'H/D: H for headlines, D for details:',0
	DW	ANSWER
	DW	0		;<==== NEEDS HELP MSG #
	DB	3
	LXI	H,NEWSFL
	LDA	ANSWER
	CPI	CR
	JZ	FUNCT
;	CPI	'D'
;	JZ	NEWSTYP	;TYPE ALL
	CPI	'H'
	JNZ	NEWSCMD
	CALL	TYPEFH	;ONLY HEADLINES
	JMP	FUNCT	;O O	O
;CBBS	O O O	O O O	  O	O O O	.ASM
;	O   O	O   O	  O 	    O
;	O   O	O   O	  O 	O O O
;
;MOD LOG (THRU 3.2 WRITTEN TO "H;TOGGLE EXPERT USER FLAG
;
05;MODS:
XPERT	CALL	TOGGLEX
	JMP	FUNCT
;
TOGGLEX	LDA	EXPERT	;TOGGLE..
	CMA		;..THE..
	STA	EXPERT	;..FLAG
	RET
05;END
;
;VIDEO BACKSPACE MODE CHANGE:
;
;	ASKS FOR A CHAR 2 TIMES.  IF THEY MATCH, THE CHAR
;	IS SET AS AN ALTERNATE VIDEO BS CHAR.  NORMAL
;	^H STILL APPLIES.
;
VIDBS	LDA	EXPERT
	ORA	A
	JZ	VIDNX
	CALL	ILPRT
	DB	'B.S. char (Twice): ',0
	JMP	VIDBS2
;
VIDNX	CALL	ILPRT
	DB	CR,LF,'Type your choice of '
	DB	'video backspace char, 2 times:',0
VIDBS2	CALL	KEYIN	;GET IT
	CPI	CR	;C/R RETURNS
	JZ	FUNCT	;	TO MENU
	MOV	B,A	;SAVE FOR CMP
	PUSH	B	;SAVE
	CALL	KEYIN	;GET SECOND
	POP	B	;GET FIRST
	CMP	B	;SAME?
	JNZ	VDIFF	;	NO, SAY SO
	LXI	H,VNACH	;VIDEO, NOT ALLOWED
	CPI	'0'	;DISALLOW 0
	JC	VCMP
	CPI	'9'+1	;	THRU 9
	JC	VNALOW	;	
	CPI	'A'	;DISALLOW A
	JC	VCMP
	CPI	'Z'+1	;	THRU Z
	JC	VNALOW
	CPI	'A'+20H	;DISALLOW LOWER CASE A
	JC	VCMP
	CPI	'Z'+1+20H	;	THRU Z
	JC	VNALOW
;
;TEST FOR CERTAIN CONTROL CHARS NOT ALLOWED,
;	^U, ^R, ^W
;
VCMP	MOV	A,M
	CMP	B
	JZ	VNALOW
	INX	H
	ORA	A
	JNZ	VCMP
	MOV	A,B
	STA	BSCHAR
	CALL	ILPRT
	DB	CR,LF,'++SET++',CR,LF,0
	JMP	FUNCT
;
VNALOW	CALL	ILPRT
	DB	CR,LF
	DB	'Alpha, numeric, or system ctl chars '
	DB	'(U, R, W) not allowed',CR,LF,0
	JMP	VAGAIN
;
VNACH	DB	'U'-'@','R'-'@','W'-'@',0
;
VDIFF	CALL	ILPRT
	DB	CR,LF
	DB	'No match.  ',0
VAGAIN	CALL	ILPRT
	DB	CR,LF
	DB	'Try again. C/R to quit',CR,LF,0
	JMP	VIDBS
;
;GET PASSWORD TO GO INTO OPERATOR MODE
;
GETPW	LDA	INBUF+4	;MUST HAVE BEEN "PASS",CR
	CPI	CR
	JNZ	WHATM
	LXI	H,PASSFL ;POINT TO FILENAME
	CALL	SETRD	;OPEN FILE
	JC	NOPWF	;NOT FOUND
	CALL	RDBYTE	;PRIME BUFFER
PWAGIN	CALL	CRLF	;PROMPT ONLY W/CRLF
	LXI	H,80H	;POINT TO PASSWORD
	MVI	B,0	;INIT UNEQ CHAR COUNT
GETPWL	CALL	KEYIN
	CPI	60H	;LOWER CASE?
	JC	GPNUC
	CPI	7FH
	JZ	PWAGIN
	ANI	5FH	;MAKE UPPER CASE
GPNUC	CPI	'U'-40H	;CTL-U?
	JZ	PWAGIN
	CMP	M
	JZ	PWEQ	;EQUAL CHAR
	MVI	B,1	;SHOW INVALID
PWEQ	INX	H
	SUI	CR	;END?
	JNZ	GETPWL
;ALL CHARS MATCH?
	ORA	B	;CHECK B
	STA	PASSFLG	;SET FLAG, 0=OK
	JZ	PWOK	;OK. GOT IT.
;
;LOG FAILURE TO ENTER CORRECT PASSWORD
;
	LXI	H,LOGFL	;POINT TO FILENAME
	CALL	EXTEND
	CALL	WRCRLF
	MVI	A,']'
	CALL	WRBYTE
	LXI	H,PASSFL+1 ;POINT TO "PASSWORD"
	CALL	WRVAR	;WRITE IT
	MVI	A,' '
	CALL	WRBYTE
	CALL	WRNAME
06;	CALL	WRCRLF
	CALL	WREOF
	JMP	WHATM	;PROMPT "DON'T UNDERSTAND"
;
;IF THERE IS A NOTES FILE, TYPE IT
;
PWOK	LXI	H,NOTEFL
	CALL	TYPEF	;TYPE NOTES FILE
	JMP	FUNCT
;
NOPWF	CALL	ILPRT
	DB	'++NO PASSWORD FILE',0
	JMP	FUNCT
;
;WAIT 3/4 SEC FOR CTL-C TO BE TYPED
;
CTLCWT	LXI	H,0	;APPROX 1 SEC @ 2MHZ, .5 AT 4.
CTLCW2	DCX	H
	MOV	A,H
	ORA	L
	JNZ	CTLCW2
	JMP	CTLCKS	;CHECK CTL-C, RETURN
;
	IF	TWITCK
;'TWIT' TEST OF NAME, RET ZERO IF INVALID NAME
;
;A "TWIT" IS SOMEONE LIKE "JOE,JOE" OR "BO,BO" WHICH
;CBBS/CHICAGO IS PLAGUED WITH, SO AT LEAST WE
;DENY HIM MESSAGE ACCESS.
;
TWITST	LDA	LNAME+1	;A TWIT WOULD USE..
	CPI	0DH	;..ONLY A LAST INITIAL
	JZ	ISTWIT
	LXI	H,LNAME
	LXI	D,FNAME
TWITLP	LDAX	D
	CMP	M
	RNZ
	INX	D
	INX	H
	CPI	0DH
	JNZ	TWITLP
ISTWIT	LDA	TWITCT
	INR	A
	ANI	3
	STA	TWITCT
	JZ	BYETWIT
	XRA	A
	RET
BYETWIT	MVI	A,1
	STA	CTLKSW
	JMP	BYEBYE
TWITCT	DB	0
	ENDIF		;TWITCK
;
	LINK	CBBSBYE
