;CBBS V3.5.0 	FILE CBBS.ASM - MAINLINE
;01/03/82 16:02:40 Put in new .asm date, cbbssub2 mod'd
;12/04/81 08:50:41 Set CBBSCHI=FALSE
;LINKS TO CBBSFUNC.ASM
;
VERS	EQU	3	;PRINTED AT SIGNON
MODIF	EQU	5	;(9 MAX)
LEV	EQU	0	;(9 MAX)
;
;	O O O	O O	O O	O O O
;	O	O   O	O   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 O O
;
;---------------------------------------
;
;	O   O	O O O	O O O	O O O
;	OO  O   O   O	  O	O
;	O O O	O   O	  O	O O	O
;	O  OO	O   O	  O	O
;	O   O	O O O	  O	O O O	O
;
;_THIS PROGRAM MUST BE ASSEMBLED WITH
;	"LINKASM.COM" WHICH HANDLES THE "LINK"
;	PSEUDO-OPS AT THE END OF EACH FILE,
;	WHICH LINKS TO THE NEXT .ASM FILE
;		----------------
;
;"CBBS"(R)  COMPUTERIZED BULLETIN BOARD SYSTEM (R)
;IS COPYRIGHT (C) WARD CHRISTENSEN, 1978, 1979, 1980, 1981
;
;	01/26/78
;ORIGINALLY WRITTEN, SITTING HOME SNOWBOUND
;BY WARD CHRISTENSEN
;
;ALL COMMENTS REGARDING MODIFICATION are recorded
;in "HISTORY" files.  HISTORY.DOC contains the comments
;for modifications for ALL .ASM files thru version 3.2;
;
;At times, modifications are indicated in the margin by 
;a number, corresponding to the number in the HIST... file.
;This idea was later abandoned as being "too much house-
;keeping".
;
;====> HISTORICAL COMMENTS SINCE 3.3 TO "HISTORY.033"
;
	ORG	100H
FALSE	EQU	0
TRUE	EQU	NOT FALSE
;
02 FAST		EQU	FALSE	;RUNNING CBBS UNDER "FAST"?
04 CCOUNT	EQU	35	;MAX COMMENT LINES/CALL
04 ECOUNT	EQU	7	;MAX MSGS ENTERED/CALL
05 TEST		EQU	true 	;TEST VERSION FOR NON-MODEM
;				;ALTERNATIVE TO "TEST" IS LOAD.SUB
10 CBBSCHI	EQU	FALSE	;WANT DRIVE DESELECT? (0C OUT FC)
;
REINIT	EQU	true 	;SET TRUE IF SYS NOT RELOADED
;			 EACH TIME IT IS RUN
NOTIFY	EQU	TRUE 	;NOTIFY FROM "NEXT" FILE?
LINE2	EQU	FALSE
;
CLOCKC	EQU	FALSE	;COMPU-TIME CLOCK? (FILE CBBSCLKC.ASM)
CLOCKS	EQU	false	;SCITRONICS CLOCK? (FILE CBBSCLKS.ASM)
CLOCK	EQU	CLOCKC OR CLOCKS ;HAVE HARDWARE CLOCK?
;
TTY	EQU	false 	;IS THERE A LOG TTY?
KBUFPG	EQU	08	;8 PAGE, 2K FOR KILLING
;----
;
;NOTE THE ONLINE BULLETIN ADD ISN'T THAT GREAT -
;(THAT'S A NICE WAY OF SAYING "TERRIBLE")
;WE SUGGEST MAINTAINING THE BULLETIN WITH THE
;CP/M EDITOR, THUS BULL EQU FALSE
;
BULL	EQU	FALSE	;ONLINE BULLETIN ADD?
;		----------------
03;START OF MODS
;DIVISOR FOR # OF MSG FILES.  LAST 2 DIGITS
;OF MSG FILE ARE DIVIDED BY THIS #.  THEREFORE:
;	2	 MEANS	50 FILES
;	3		34 FILES
;	4		25 FILES
;	5		20 FILES ..ETC.
;
FILEDIV	EQU	2	;50 MSG FILES IN CBBS/CHICAGO
03;END OF MODS
;
TTYST	EQU	80H	;STATUS BIT (JZ WAIT LOOP)
TTYSP	EQU	0	;TTY STATUS PORT
TTYDP	EQU	1	;TTY DATA PORT
SSW	EQU	3   	;SENSE SWITCH PORT
REMOTE	EQU	0ffH	;SSW ON FOR REMOTE
EJECT	EQU	FALSE	;EJECT TTY EVERY 60 LINES?
TWITCK	EQU	TRUE	;ABORT IF INVALID USER NAME
UKILL	EQU	1	;TRUE, USER CAN KILL OWN MSGS
;
HAYES	EQU	FALSE	;HAVE HAYES MODEM?
IDS	EQU	FALSE	;HAVE  IDS  MODEM?
PMMI	EQU	false 	;HAVE PMMI  MODEM?
SERMODM	EQU	true	;HAVE SERIAL MODEM?
;
B450600	EQU	TRUE 	;450, 600 BAUD (PMMI, IDS ONLY)
;
CR	EQU	0DH
LF	EQU	0AH
EOF	EQU	1AH
TAB	EQU	09H
;
; -------->   NOTE THE FOLLOWING <---------
;
;THE FOLLOWING ADDRESS IS  O-U-T-S-I-D-E
;OF THIS PROGRAM.  IT IS A BYTE WHICH CONTAINS
;A CONTINUALLY RUNNING LINE COUNT FOR THE
;LOGGING TTY.  IT NEED NOT BE INITIALIZED,
;BECAUSE THE COUNTER WILL EVENTUALLY REACH 60,
;AND GET IN SYNC.  THE COUNTER IS N-O-T REF-
;ERENCED IF EITHER 'EJECT' OR 'TTY' IS FALSE.
;
;TTYLCT	EQU	0EFF0H	;IN PROM BOARD'S RAM AREA
;
	JMP	START
;
;IF CLOCK BOARD, DEFINE CURRENT YEAR SO IT
;MAY BE EASILY PATCHED AT YEAR CHANGE (THEY
;BECOME THE 4TH AND 5TH BYTES OF THE .COM FILE)
;
	IF	CLOCKC	;Computime doesn't keep year.
Y1	DB	'8'	;DEFINE CURRENT..
Y2	DB	'2'	;..YEAR PRINTED
	ENDIF
;
	DB	'< Copyright (C) 1981, Ward Christensen >'
	DB	'[01/03/82 16:02:40]'
	DB	1AH	;^Z TO ALLOW "TYPE CBBS.COM"	
;
START	LXI	SP,STACK
	CALL	INIT	;SET UP I/O JMP ADDRESSES
;
;PICK UP THE PHONE, CHECK FOR CARRIER FOR 15 SEC.
;
05	IF	NOT TEST
	IN	SSW	;READ SSW
	ANI	80H	;REMOTE?
	CNZ	CONNECT		(EXITS IF NO CARRIER)	
	endif
;
;PRINT VERSION
;
	MVI	B,6	;SEND 6..
	CALL	NULLP	;..NULLS
	CALL	ILPRT
	DB	'CBBS(R) '
	DB	'0'+VERS,'.'
	DB	'0'+MODIF,'.'
	DB	'0'+LEV
	DB	CR,LF,0
;
;PRINT DATE/TIME
;
 IF CLOCK
	MVI	A,1	;DISABLE..
	STA	CTLCSW	;..CTL-C
	MVI	B,6	;DO 6 NULLS..
	CALL	NULLP	;..BEFORE TIME
	CALL	PRTIME	;PRINT DATE,TIME
	LXI	H,LGINTIM
	CALL	RDTIME	;SAVE LOGIN TIME
	XRA	A	;SHOW CTL-C..
	STA	CTLCSW	;..ENABLED
 ENDIF
;
;09/13/81 MODS TO WRITE DATE/TIME TO HARD-COPY LOG
;
 IF CLOCK AND TTY
	MVI	A,50
	STA	COL	;FORCE C/R AFTER DATE/TIME
	LXI	H,ANSWER ;WHERE "RDTIME" STORED DATE/TIME
LOGTIME	PUSH	H
	MOV	A,M
	CALL	LOG
	POP	H
	INX	H
	MOV	A,M
	ORA	A
	JNZ	LOGTIME
	MVI	A,CR
	CALL	LOG
 ENDIF
;09/13/81 END
;
;CHECK FOR CTL-C, TO SAVE OPENING WELCOME FILE
;
WELL1	CALL	CTLCWT	;WAIT 3/4 SEC, THEN TRY
	LXI	H,WELCOM ;POINT TO FILENAME
	CNZ	TYPEF	;TYPE THE WELCOME FILE
;
;TYPE BULLETIN FILE IF IT EXISTS
;
NOWEL	CALL	CRLF
;
;CHECK FOR CTL-C, TO SAVE OPENING BULLETIN FILE
;
	CALL	CTLCWT	;WAIT 3/4 SEC FOR CTL-C
	LXI	H,BULFL	;POINT TO FILE
	CNZ	TYPEF	;TYPE IF NO CTL-C
;
;IF THIS IS THE USERS FIRST TIME ON THE SYSTEM,
;PROCESS THE FILE 'FIRSTIME' WHICH SUPPLIES
;SOME INFO ON THE SYSTEM'S USAGE.
;07/15/81 ^K COMES HERE NOW IF CTLKSW SET TO 4.
;
ASKT1	MVI	A,CR	;BLANK 'WHERE FROM' FIELD
	STA	SUBJ	;..IN CASE IT'S NOT ENTERED.
	MVI	A,0FFH	;ALLOW..
	STA	CASE	;..LOWER CASE
	CALL	GETVAR
	DB	CR,LF
	DB	'Y/N: IS THIS YOUR FIRST TIME ON CBBS',0
	DW	ANSWER
06	DW	1	;HELP MSG #
	DB	9	;MAX ANSWER LEN
;
;LOOK AT FIRST CHAR IN BUFFER (INSTEAD OF THE ONE
;IN 'ANSWER', TO SEE IF LOWER CASE WAS ENTERED
;
	LDA	FIRSTCH	;GET UN-TRANSLATED 1ST CHAR
	CPI	60H	;LOWER CASE?
	JNC	T1LC	;IT IS LOWER CASE
	MOV	B,A	;SAVE CHAR
	MVI	A,05FH	;SET UPPER CASE
	STA	CASE
	MOV	A,B	;GET CHAR
T1LC	ANI	5FH	;MAKE UPPER CASE
	STA	T1FLAG	;"REMEMBER" IF 1ST TIME
	CPI	'N'
	JZ	GETFN
	CPI	'Y'
	JNZ	ASKT1
;
;IF UPPER CASE, ASK IF LOWER CASE CAN BE HANDLED
;
	LDA	CASE
	INR	A	;ZERO => LOWER CASE
	CNZ	QCASE	;SEE IF CAN HANDLE LOWER CASE
;
;ASK WHERE CALLING FROM
;
WHERE	CALL	GETVARN
	DB	CR,LF
;	DB	'(Optional) ',CR,LF
	DB	'What city,state/prov. are you calling from',0
	DW	SUBJ	;TEMP STORE IT HERE
06	DW	0	;NO HELP MSG #
	DB	30	;MAX LEN
	LXI	H,TIME1	;POINT TO FILENAME
	CALL	INTQF	;INTERPRET THE QUESTION FILE
;
;GET CALLER'S NAME
;
GETFN	CALL	GETVAR	;GET THE NAME
	DB	'What is your FIRST name',0
	DW	FNAME
06	DW	2	;HELP MSG #
	DB	19	;MAX LEN
	LDA	FNAME
	CPI	'A'	;FORCE ALPHA
	JC	GETFN
	CPI	'Z'+1
	JNC	GETFN
GETLN	CALL	GETVAR
01	DB	'(Press return to return to "first name" '
01	DB	'question)',CR,LF
	DB	'What is your LAST name',0
	DW	LNAME	;READ LAST NAME
06	DW	2	;HELP MSG #
	DB	19	;MAX LEN
	LDA	LNAME
	CPI	CR
	JZ	GETFN
06	CPI	'-'
06	JZ	GETFN
	CPI	'A'	;FORCE ALPHA
	JC	GETLN
	CPI	'Z'+1
	JNC	GETLN
;
;MAKE SURE FIRST + LAST NOT > 20 CHARS
;
	LXI	H,FNAME
	CALL	COUNTC0	;INIT B=0, COUNT CHARS
	LXI	H,LNAME
	CALL	COUNTC
	MOV	A,B	;GET COUNT
	CPI	20	;+ 1 SPACE BETWEEN
	JC	CKNOK	;CHECK IF NAME OK
	CALL	ILPRT
	DB	'Sorry, first name + last name '
	DB	'may not be > 19 long',CR,LF,0
	JMP	GETFN
;
;IF FIRST TIME USER, ASK IF NAME SPELLED OK.
;
;EXPERIENCED USERS DON'T NEED THIS QUESTION,
;AS THEY SHOULD KNOW CTL-U, DEL, ETC EDITING.
;
CKNOK	LDA	T1FLAG	;1ST TIME?
	CPI	'N'
	JZ	LOGIN	;NOT 1ST TIME
	CALL	ILPRT
	DB	'Hi, ',0
	LXI	H,FNAME
	CALL	TYPEMCR	;TYPE FIRST NAME
	MVI	A,' '
	CALL	TYPE
	LXI	H,LNAME
	CALL	TYPEMCR	;TYPE LAST NAME
01	CALL	GETVARN
	DB	CR,LF
	DB	'Y/N Did I get your name right',0
	DW	ANSWER
06	DW	0	;NO HELP MSG #
	DB	9	;MAX ANSWER LEN
	LDA	ANSWER
01	ANI	5FH	;UPPER CASE
	CPI	'N'
	JZ	GETFN
	CPI	'Y'
	JNZ	CKNOK
	CALL	ILPRT
	DB	'(NOTE: correcting done only if '
	DB	'this is your first time)',CR,LF,0
;
;LOG: (DATE TIME [IF THERE IS A CLOCK BOARD])
;(CALLER #),(FIRST NAME),(LAST NAME),(WHERE FROM)
;
LOGIN	CALL	ILPRT
	DB	CR,LF
	DB	'Logging ',0	;name to disk...',0
	lxi	h,fname
	call	typemcr
	mvi	a,' '
	call	type
	lxi	h,lname
	call	typemcr
	call	ilprt
	db	' to disk ....',0
	MVI	A,1
	STA	DKUPSW	;SET DISK UPDATE IN PROGRESS
	STA	CTLKSW	;DISALLOW CTL-K
;GET THE CALLER # FROM FILE "NEXT"
; (FORMAT IS: NNNNN(CR)(LF)CCCCC(CR)(LF)
04;AAAAA(CR)(LF)MMMMM(CR)(LF)(CTL-Z)
; WHERE NNNNN IS NEXT MSG #, CCCCC IS CALLER #,
; AAAAA IS THE # OF ACTIVE MESSAGES
04;MMMMM IS MAX ACTIVE MSGS).
	CALL	RDNEXT
;SAVE CALLER # SO IT CAN BE LOGGED
	LXI	H,87H	;FROM,
	LXI	D,CALLERN ;..TO,
	MVI	B,6	;..LENGTH
	CALL	MOVE	;MOVE INCL. C/R
	LXI	H,LOGFL	;POINT TO FILENAME
	CALL	EXTEND	;EXTEND THE FILE
;
09	CALL	WRCRLF	;CRLF BEFORE
;
;WRITE DATE AND TIME TO LOG FILE
	IF	CLOCK
	CALL	WRTIME
	ENDIF		;CLOCK
;
	LXI	H,CALLERN
	CALL	WRVARC	;WRITE CALLER #,
	LXI	H,SPEED	;WRITE BAUD RATE
	CALL	WRVARC	;(1, 3, 4, OR 6)
	CALL	WRNAME	;"FN LN,"
	LXI	H,SUBJ	;AND 'WHERE FROM'.
	CALL	WRVARC
;
09;NOP THE CALL WRCRLF, SO THE E.T. WILL FOLLOW.
;	CALL	WRCRLF	
	CALL	WREOF	;CLOSE FILE
	CALL	CRLF
	XRA	A	;GET 0
	STA	DKUPSW	;NOT UPDATING DISK
;09/13/81 KILL INSTR PER LEWIS MOSELEY,
;		'CAUSE TWITS COULD ^K PAST NAME CHECK
;	STA	CTLKSW	;ALLOW CTL-K
;
;EDIT 01 PULLED CODE OUT OF HERE, MOVED TO
;"STATSUB" AT END OF CBBS.ASM
;
01	CALL	ILPRT
01	DB	'You are',0
01	CALL	STATSUB	;PRINT CALLER, MSG, MSGS
;
;WRITE BACK FILE W/MSG # AND CALLER #
;
	XRA	A
	STA	FCBRNO	;BACK TO SECTOR 0
	LXI	D,FCB
	MVI	C,WRITE
	CALL	BDOS	;WRITE BACK
	ORA	A	;WAS IT OK?
06;MODS:
	JNZ	NXERR
	LXI	D,FCB
	MVI	C,CLOSE
	CALL	BDOS
	INR	A	;returns -1 on error
	JZ	NXERR
;
;12/09/78 ADD NOTIFY TEST
;
	IF	NOT NOTIFY
	JMP	FUNCT
	ENDIF
;
	IF	NOTIFY
	JMP	CKMSGS
	ENDIF
;
NXERR	CALL	ILPRT
06;END OF MODS
	DB	'++Error writing caller #',CR,LF,0
	JMP	TELLUS
;
	IF	NOTIFY
;
;LOOK IN "NEXT" FILE FOR A MSG TO THIS CALLER
;
CKMSGS	CALL	RDNEXT	;PRIME BUFFER
CKNLP	CALL	RDBYTE
	JC	FUNCT	;NO MSGS
	CPI	'['	;NAME HDR?
	JNZ	CKNLP
;MATCH THE NAME
	LXI	H,FNAME
	CALL	MATCH
	JNZ	CKNLP
	LXI	H,LNAME
	CALL	MATCH
	JNZ	CKNLP
;
;OK, NAME MATCHED.
;
	CALL	CRLF
CKNTLP	CALL	RDBYTE
	JC	FUNCT
	CPI	']'	;END OF MSG?
	JZ	CKNSY
	CALL	TYPE
	JMP	CKNTLP
;
;CHECK NAME FOR SYSTEM FUNCTION:
;
; 	/	HANG UP ON THE CALLER
;	*	FLAG AS "TWIT" (NO KILL, ENTER)
;	$	KEEP TRACK OF LAST CALL (not implemented)
;
CKNSY	CALL	RDBYTE
	CPI	'/'
	JZ	DISC	;DISCONNECT
	CPI	'*'
	JZ	TWITSET
	CPI	'+'	;IF '+', CONTINUE (TO ALLOW
	JZ	CKNLP	;	INDIVIDUAL + "*.*".
	CPI	'$'
;
;NOTE REMOVE THE FOLLOWING ';' WHEN 'LASTUSE'
;FUNCTION IS DEFINED
;
;	JZ	LASTUSE
	JMP	FUNCT
TWITSET	MVI	A,1
	STA	TWITSW
	JMP	FUNCT
;
;MATCH A NAME AGAINST THE FILE
;
MATCH	CALL	RDBYTE
	JC	FUNCT
	CPI	'*'	;MATCH ANY?
	JZ	MATCHOK
	CPI	','	;DELIM?
	JZ	MATCHCR	;YES
	CMP	M	;CHAR MATCH?
	RNZ		;..NO
	INX	H
	JMP	MATCH
;
;OK, SKIP TO NEXT DELIM
;
MATCHOK	CALL	RDBYTE
	JC	FUNCT
	CPI	','	;DELIM?
	RZ		;YES
	JMP	MATCHOK
;
;MATCH THE C/R AT END OF NAME
;
MATCHCR	MOV	A,M
	CPI	0DH
	RET		;ZERO SET IF OK
	ENDIF		;NOTIFY
;
;"#" COMMAND (STATS)
;
01 STATS CALL	ILPRT
01	DB	'Next',0
01	CALL	STATSUB	;PRINT
01	JMP	FUNCT
;
;TYPE CALLER #, HI MSG #, # OF MSGS.
;CALLED AT LOGON, AND BY # (STATS) FUNCTION.
;
01 STATSUB	CALL	ILPRT
	DB	' caller ',0
	CALL	RDNEXT	;GET "NEXT" TO 80H
	LXI	H,87H	;POINT TO NUMBER
01; FOLLOWING COMMENTED OUT - WAS IN ERROR
;	PUSH	H	;FOR MOVE
	CALL	TYPEMCR
;	CALL	CRLF
;
;INCREMENT CALLER # (NOP ON # COMMAND, BECAUSE
;ITS NOT WRITTEN BACK)
;
	LXI	H,8BH	;TO UNITS DIGIT
	CALL	ADD1
;
;TYPE THE NEXT MESSAGE NUMBER
;
	CALL	ILPRT
	DB	'; next msg =',0
	LXI	H,80H	;POINT TO NUMBER
07	PUSH	H	;SAVE POINTER
	CALL	TYPEMCR
;	CALL	CRLF
;
;TYPE # OF ACTIVE MESSAGES
;
	CALL	ILPRT
	DB	';',0
	LXI	H,8EH
	CALL	TYPEMCR
	CALL	ILPRT
	DB	' active msgs.',CR,LF,0
07;MODS:
;
;SAVE HI MSG # FOR "R;-"
;
	POP	H	;MSG # POINTER
	LXI	D,MSGNO
	MVI	B,5
	CALL	MOVE
07;END
;
	RET
;
link	cbbsfunc
;
;
;
autosc	lxi	h,inbuf
fndcr	mov	a,h
	inx	h
	cpi	cr
	jnz	fndcr
	lxi	d,scstr
	mvi	b,10
	call	mvlnm
	lxi	d,lname
	call	mvlnm5
	lxi	d,frmstr
	call	mvlnm5
	lxi	d,lname
	call	mvlnm5
	dcx	h
	mvi	a,cr
	cmp	m
	jz	gfnc
	inx	h
	mov	m,a
gfnc	jmp	funct
;
mvlnm5	mvi	b,5
mvlnm	dcx	h
	mov	a,m
	cpi	cr
	jz	mvlp
	inx	h
mvlp	ldax	d
	mov	m,a
	cpi	cr
	inx	h
	inx	d
	rz
	djnz	mvlp
	ret
;
scstr	db	';s;30,t='cr,0
frmstr	db	';f=',cr,0
;
LINK	CBBSFUNC ;NEXT .ASM FILE
