;CBBS V3.5.0 	CBBSENT2.ASM - MSG ENTRY, PART 2
;08/02/81 13:22:04
;	LINKS TO CBBSRTRV
;
;	O O O	O   O	O O O	 O O 
;	O	OO  O	  O	O   O
; CBBS	O O	O O O	  O	   O	.ASM
;	O	O  OO	  O	 O
;	O O O	O   O	  O	O O O
;
;FILE CONTAINS MESSAGE ENTRY SUBFUNCTIONS:
;	(A)bort
;	(C)ontinue
;	(D)elete
;	(E)dit
;	(G)et msg
;	(H)elp
;	(I)nsert
;	(L)ist
;	(R)e-type
;	(S)ave.
;
;	e(X)pert mode may also be switched, but this
;		is a function of GETVAR, not msg entry.
;
;====> HISTORICAL COMMENTS SINCE 3.3 TO "HISTORY.033"
;
;		--------
;
;COME HERE FOR ENTER MODE SUBCOMMANDS,
;OR IF CTL-K TYPED DURING MSG ENTRY
;
ENCOMD:
01	LXI	SP,STACK
	LHLD	LINEAD
	MVI	M,0	;SET END OF MSG
	LDA	EXPERT
	ORA	A
	JNZ	ENREQ
;
ENASIST	CALL	ILPRT
	DB	CR,LF
	DB	'Enter 1 letter: then press return.'
	DB	CR,LF
	DB	'(A)bort, (C)ontinue, (D)elete, '
	DB	'(E)dit, (G)et msg, (H)elp,',CR,LF
	DB	'(I)nsert, (L)ist, (R)e-type',CR,LF
	DB	'(S)ave <--- (DO THIS WHEN '
	DB	'YOU HAVE FINISHED) ',0
ENREQ	LDA	INBUF	;STACKED ANS?
	CPI	CR
	CNZ	CRLF	;YES, CRLF
	CALL	GETVAR
	DB	CR,LF,'A,C,D,E,G,H,I,L,R,S:',0
	DW	ANSWER
02	DW	-1	;HELP MSG # (PASS BACK "?")
	DB	8	;MAX LEN (ALLOW "CONTINUE")
	LDA	ANSWER
	CPI	'?'	! JZ ENASIST
	CPI	CR	! JZ ENASIST
	CPI	'A'	! JZ VABORT
	CPI	'C'	! JZ ENCONT
	CPI	'D'	! JZ ENDEL
	CPI	'E'	! JZ ENEDIT
	CPI	'G'	! JZ ENGET
	CPI	'H'	! JZ ENHELP
	CPI	'I'	! JZ ENISRT
	CPI	'L'	! JZ ENLIST
	CPI	'R'	! JZ ENRETYP
	CPI	'S'	! JZ ENSAVE
;
	JMP	ENCOMD	;BAD - ASK AGAIN
;
;'C' SUBCOMMAND: CONTINUE ENTERING (UNLESS FULL)
;
ENCONT	LDA	MSGBF+15*64 ;TO LAST LINE
	ORA	A	;0 => EMPTY
	JZ	ENLOOP	;OK, ROOM FOR MORE
	JMP	ENFULL	;IT'S FULL, CAN'T CONTINUE
;
;DELETE A LINE
;
ENDEL	LDA	INBUF	;LINE # ALREADY GIVEN?
	CPI	CR	;BUFFERED ANSWER?
	JNZ	ENDEL2	;YES.
	CALL	ILPRT
	DB	'Delete ',0
ENDEL2	CALL	ENGETL	;GET LINE #
	JZ	ENCOMD	;NO LINE
ENDELP	MVI	M,0	;KILL THE LINE
	MOV	A,C	;GET LINE #
	CPI	16	;DONE?
	JZ	ENDEND	;..YES
	XCHG		;MOVE UP..
	LXI	H,64	;..1 LINE
	push	b
	lxi	b,64
;	MOV	B,L	;B=64
	DAD	D	;DE=PREV, HL=NELINES, MUST GET EOM.
	ldir
	xchg
	pop	b
	inr	c
	jmp	endelp
;
;	CALL	RDBYTE
;	JC	ENGEOF
;	CPI	7
;	JZ	ENGEOF
ENDEND	CALL	ILPRT
	DB	'++Deleted++',CR,LF,0
;
;fix up the hi line number AND POINTER
;
	LHLD	LINEAD	;HI LINE PTR
	LXI	D,-64
	DAD	D
	SHLD	LINEAD
;
	LXI	H,LINO+1 ;TO ASCII #
03;MODS
	CALL	SUB1
	LXI	H,HILINE+1
	CALL	SUB1
03;END
	JMP	ENCOMD
;
;'I' SUBCOMMAND: INSERT A LINE
;
ENISRT	LDA	MSGBF+15*64 ;ALREADY 16 LINES?
	ORA	A
	JNZ	ENFULL	;YES, FULL
	LDA	INBUF	;LINE # ALREADY GIVEN?
	CPI	CR	;BUFFERED ANSWER?
	JNZ	ENIS2	;YES.
	CALL	ILPRT
	DB	'Insert before ',0
ENIS2	CALL	ENGETL	;GET LINE #
	JZ	ENCOMD	;NO LINE
;C = BINARY LINE #, HL = ADDR
	SHLD	ENISAD	;SAVE ADDRESS FOR INPUT
	LXI	B,MSGBF+15*64 ;PAST 2ND LAST LINE
	LXI	D,MSGBF+16*64 ;PAST LAST LINE
;
;MOVE THE LINES APART TO MAKE ROOM FOR INSERT
;THIS IS A "TOP DOWN" (BACKWARDS) MOVE.
;
ENISMV	DCX	B	;BACK..
	DCX	D	;..UP 1
	LDAX	B
	STAX	D
;SEE IF DONE
	MOV	A,B	;PAGES MATCH?
	CMP	H	;AT LINE?
	JNZ	ENISMV	;NO, LOOP
	MOV	A,C	;LOW MATCH
	CMP	L
	JNZ	ENISMV
;
	CALL	GETVARN
	DB	'Type the inserted line',CR,LF,0
ENISAD	DW	$-$
02	DW	16	;HELP MSG #
	DB	60
;
;INCREMENT HI ADDR, LINE #, BECAUSE OF THE
;INSERTED LINE
;
	LXI	H,LINO+1
	CALL	ADD1	;BUMP IN ASCII
03	LXI	H,HILINE+1
03	CALL	ADD1	;BUMP HI LINE #
	LHLD	LINEAD
	LXI	D,64
	DAD	D
	SHLD	LINEAD
	JMP	ENCOMD
;
;TYPE HELP FILE FOR ENTER FUNCTION
;
ENHELP	LXI	H,ENHLFL ;'ENTRHELP'
	CALL	INTQF	;INTERPRET THE QUESTION FILE
	JMP	ENCOMD
;
;LIST THE MESSAGE
;
ENLIST	LDA	INBUF	;LINE # ALREADY GIVEN?
	CPI	CR	;BUFFERED ANSWER?
	JNZ	ENLIS2	;YES.
	CALL	ILPRT
	DB	'Starting ',0
ENLIS2	CALL	ENGETL	;GET LINE #
	JZ	ENCOMD	;NO LINE #
	MOV	A,C	;GET LINE #
	LXI	B,'00'
ENLIS3	INR	C
	DCR	A
	JNZ	ENLIS3
;BC NOW HAS ASCII NUMBER, MAY REQUIRE DECIMAL ADJUST
	MOV	A,C
	CPI	'9'+1
	JC	ENLIS4
	INR	B	;CARRY
	SUI	10	;ADJUST
	MOV	C,A
ENLIS4	LXI	D,64
ENLINE	MOV	A,M	;END?
	ORA	A
	JZ	ENCOMD	;DONE
	MOV	A,B
	CALL	TYPE
	MOV	A,C
	CALL	TYPE
	MVI	A,' '
	CALL	TYPE
	CALL	CTLCKS
	JZ	ENREQ
	PUSH	H
	PUSH	B
	CALL	TYPEMCR
	CALL	CRLF
	POP	B
	POP	H
	DAD	D
	INR	C
	MOV	A,C
	CPI	'9'+1
	JC	ENLINE
	LXI	B,'01'	;'10' REVERSED
	JMP	ENLINE
;
;'G' SUBCOMMAND: GET AN EXISTING MESSAGE
;
ENGET	LXI	H,MSGNO	;SAVE..
	LXI	D,SAVMSG ;..CURR..
	MVI	B,5	;..MSG #
	CALL	MOVE	
	CALL	GETVAR
	DB	CR,LF
	DB	'MSG #: to get (C/R if none) ',0
	DW	ANSWER
02	DW	16	;HELP MSG #
	DB	5	;MSG # LEN
	LDA	ANSWER	;JUST..
	CPI	CR	;..CR?
	JZ	ENCOMD	;
	CALL	JUSTA	;RIGHT JUSTIFY INTO 'MSGNO'
	JC	ENGET	;BAD NUMBER
	CALL	SETMSGN	;SETUP FILENAME
	LXI	H,MSGFN	;POINT TO 'MESSAGE ',MSGNO
	CALL	SETRD	;SET UP TO READ
	JC	ENGNSM	;NO SUCH MSG FILE
;
;SCAN FOR BELL HDR
;
ENGBEL	CALL	RDBYTE
	JC	ENGNSM	;NO SUCH MSG
	CPI	7	;HDR?
	JNZ	ENGBEL
;
;GOT HDR, SEE IF RIGHT ONE
;
	LXI	H,MSGNO	;GOT BELL,..
	MVI	B,5	;..MATCH MSG
ENGSRM	CALL	RDBYTE
	JC	ENGNSM
	CMP	M
	JNZ	ENGBEL	;NOT IT, GET NEXT
	INX	H
	DCR	B	;=, CONTINUE
	JNZ	ENGSRM
;
;GOT THE MESSAGE.  READ IT IN.
;
	CALL	RDBYTE	;EAT ','
	MVI	B,4	;TYPE THRU 4 COMMAS
;
;ECHO THE PREV HDR
;
ENGHDR	CALL	RDBYTE
	JC	ENGNSM
	PUSH	PSW
	CALL	TYPE
	POP	PSW
	CPI	','
	JNZ	ENGHDR
	DCR	B
	JNZ	ENGHDR
	CALL	CRLF
;
;SKIP THE PASSWORD
;
ENGSKP	CALL	RDBYTE
	JC	ENGBAD	;BAD MSG
	CPI	LF
	JNZ	ENGSKP
;
;POINTING TO MSG, READ IT IN
;
	LXI	H,'00'
	SHLD	HILINE
	INR	H
	SHLD	LINO
	LXI	H,MSGBF
	MVI	B,16	;MAX # LINES
	SHLD	LINEAD
ENGLIN	LHLD	LINEAD
	CALL	RDBYTE
	MOV	M,A
	JC	ENGEOF
	CALL	ENGTAB	;A TAB?
	CPI	7	;NEXT MSG HDR?
	JZ	ENGEOF
	INX	H
ENGCHR	CALL	RDBYTE
	JC	ENGBAD
	MOV	M,A
	CALL	ENGTAB	;TAB?
	CPI	LF
	JZ	ENGEOL	;END OF LINE?
	INX	H	;TO NEXT
	MOV	A,L
	ANI	3FH	;TO NEXT LINE?
	JNZ	ENGCHR
	SHLD	LINEAD	;SAVE LINE ADDR
	DCX	H
	MVI	M,LF
	DCX	H
	MVI	M,CR
	PUSH	B
	LXI	H,LINO
	CALL	TYPEM0
	CALL	ILPRT
	DB	' truncated.',CR,LF,0
	POP	B
;
;SKIP REMAINDER OF TRUNCATED LINE
;
ENGSKT	CALL	RDBYTE
	JC	ENGEOF
	CPI	LF
	JNZ	ENGSKT
	LHLD	LINEAD
	DCX	H
;
;GOT LINEFEED, SKIP TO END OF LINE
;
ENGEOL	INX	H
	MOV	A,L
	ANI	3FH	;TO NEXT LINE?
	JNZ	ENGEOL
	SHLD	LINEAD
	MVI	M,0	;SHOW END
	LHLD	LINO
	SHLD	HILINE
	LXI	H,LINO+1
	CALL	ADD1	;BUMP ASCII #
	DCR	B	;MORE LINES?
	JNZ	ENGLIN	;YES
;
;HAVE READ 16 LINES, MUST GET EOM.
;
	CALL	RDBYTE
	JC	ENGEOF
	CPI	7
	JZ	ENGEOF
ENGTR	CALL	ILPRT
	DB	'++Msg truncated++',CR,LF,0
;
;GOT EOF - FIXUP THINGS
;
ENGEOF	LHLD	LINEAD
	INR	B
	LXI	D,64
ENG0	MVI	M,0
	DAD	D
	DCR	B
	JNZ	ENG0
	LXI	H,HILINE
	CALL	TYPEMCR
	CALL	ILPRT
	DB	' line(s).',CR,LF,0
	CALL	ENGRSM	;RESTORE MSG #
	JMP	ENCOMD
;
;RESTORE OLD MSG #
;
ENGRSM	LXI	H,SAVMSG
	LXI	D,MSGNO
	MVI	B,5
	CALL	MOVE
	RET
;
;TEST FOR A TAB
;
ENGTAB	CPI	9	;TAB?
	RNZ		;NO
ENGTABL	MVI	M,' '	;GOT TAB..
	INX	H	;..EXPAND IT
	MOV	A,L
	ANI	7
	JNZ	ENGTABL
	DCX	H
	MVI	A,' '
	RET
;
;NO SUCH MSG
;
ENGNSM	CALL	ILPRT
	DB	'++Msg not found++',CR,LF,0
ENGRET:
01	CALL	ILPRT
	DB	'Returning to msg entry.',CR,LF,0
	CALL	ENGRSM
	JMP	ENCLR	;CLR MSG, START OVER
;
ENGBAD	CALL	ILPRT
	DB	'++Error: can''t read msg.',cr,lf,0
	JMP	ENGRET
;
;'E' SUBCOMMAND: EDIT LINE: /OLD/NEW/
;
ENEDIT	CALL	ENGETL	;GET LINE #
	JZ	ENCOMD
	SHLD	ENMAD	;SAVE POINTER
ENEDITR	CALL	ILPRT
	DB	'Line was:',CR,LF,0
	LHLD	ENMAD
	CALL	TYPEMCR
	CALL	CRLF
ENEDT2	CALL	GETVARN
	DB	'Enter: the corrections or ? for help',0
	DW	ANSWER
02	DW	-1	;HELP MSG #
	DB	60
	LDA	ANSWER
	CPI	CR
	JZ	ENCOMD
	CPI	'?'
	JNZ	EDCMP
	CALL	ILPRT
	DB	'This function does a character '
	DB	'string substitution edit.',CR,LF
	DB	'Type:  /old string/new string/',CR,LF
	DB	'New string may be null (//).',CR,LF
	DB	'When the line is correct, just '
	DB	'press return',CR,LF,0
	JMP	ENEDT2
;
;TRY TO MATCH CHAR STRINGS
;
EDCMP	LHLD	ENMAD	;GET ADDR
	MVI	C,63	;# OF COMPARES TO MAKE
EDNEXT	PUSH	H	;SAVE BUFF PTR
	LXI	D,ANSWER
	LDAX	D	;GET DELIM
	MOV	B,A	;SAVE IT
EDCOMP	INX	D
	LDAX	D	;GET NEXT
	CMP	B	;DELIM?
	JZ	EDMAT	;MATCH
	CPI	CR	;END?
	JZ	EDBAD	;BAD DELIM
	CMP	M
	INX	H
	JZ	EDCOMP
;
;NO MATCH - TRY NEXT 'WINDOW' OF LINE
;
EDNMAT	POP	H	;RESTORE LINE ADDR
	MOV	A,M
	CPI	CR
	JZ	EDBAD
	INX	H	;MOVE 1 CHAR AHEAD
	DCR	C	;MORE TO FIND?
	JNZ	EDNEXT
EDBAD	MOV	A,B	;DELIM
	CALL	TYPE
	CALL	ILPRT
	DB	': not found - '
	DB	'Type ? for help',CR,LF,0
	JMP	ENEDITR
;
;'FROM' STRING MATCHED.  NOW:
;DE= START OF 'TO' FIELD
;HL= REST OF ORIGINAL LINE
;STK= START OF DELETED STRING
;
;MOVE REST OF STRING TO WORK BUFFER
EDMAT	PUSH	D
	MVI	C,CR	;MOVE END DELIMITER
	LXI	D,80H	;RECEIVING FIELD
	CALL	MOVEC
	POP	D	;GET 'TO' FIELD
	POP	H	;GET START OF DELETED
	INX	D	;SKIP DELIMITER
;MOVE THE NEW FIELD TO THE BUFFER
EDMV1	LDAX	D	;GET NEW CHAR
	MOV	M,A
	CMP	B	;DELIM?
	JZ	EDMV1D	;MOVE DONE
	CPI	CR
	JZ	EDMV1D	;NO ENDING DELIM.
	INX	D
	INX	H
	CALL	EDCKS
	JMP	EDMV1
;NEW FIELD IS MOVED TO LINE, NOW COPY..
EDMV1D	LXI	D,80H	;..REMAINDER OF LINE
EDMV2	LDAX	D
	MOV	M,A
	CPI	CR
	JZ	EDMV2D	;ALL DONE
	INX	H
	INX	D
	CALL	EDCKS	;CHECK SIZE
	JMP	EDMV2
;MOVE ALL DONE.  PRINT NEW LINE
EDMV2D	LHLD	ENMAD
	CALL	TYPEMCR
	CALL	CRLF
	LDA	EXPERT
	ORA	A
	JNZ	ENEDT2
	CALL	ILPRT
	DB	'Continue changes (C/R when done)'
	DB	CR,LF,0
	JMP	ENEDT2
;
;CHECK IF LINE TOO LONG
;
EDCKS	MOV	A,L
	ANI	63
	RNZ
	DCX	H	;BACK UP 1
	MVI	M,CR	;PUT END
	XCHG		;END TO DE
	POP	H	;KILL RETURN ADDR
	LXI	H,-63	;POINT HL TO
	DAD	D	;	FRONT
	CALL	TRUNC	;TRUNCATE TO SPACE
	CALL	ILPRT
	DB	'++Truncated to:'
	DB	CR,LF,0
	JMP	EDMV2D
;
;---->	MOVE (HL) TO (DE), STOP WHEN MOVED CHR=(C)
;
MOVEC	MOV	A,M
	STAX	D
	INX	D
	INX	H
	CMP	C
	JNZ	MOVEC
	RET
;
;-----> SUBROUTINE TO GET VALID LINE #
;
ENGETL	LDA	MSGBF
	ORA	A
	JNZ	ENGETL2
	CALL	ILPRT
	DB	'Message is empty',CR,LF,0
	XRA	A	;SHOW
	RET		;	NOT FOUND
;
ENGETL2	CALL	GETVAR
	DB	'Line#: (C/R if none)',0
	DW	ANSWER
02	DW	16	;HELP MSG #
	DB	2
	LXI	H,0	;0 => NO LINE # ENTERED
	LDA	ANSWER
	CPI	CR	;JUST C/R?
	RZ		;YES, RET.
	CALL	GETNUM	;GET NUMBER ENTERED
	MOV	A,H	;MUST BE 0
	ORA	A
	JNZ	ENBADN
	MOV	A,L	;1<=N<=16
	ORA	A
	JZ	ENBADN
	CPI	17
	JC	ENNOK	;NUMBER IS OK
ENBADN	CALL	ILPRT
	DB	'++No such line #++'
	DB	CR,LF,CR,LF,0
	JMP	ENGETL
;
;NUMBER IS OK - CALC IT'S ADDRESS
;
ENNOK	MOV	C,L	;SAVE BINARY # IN C
	DAD	H	;X2
	DAD	H
	DAD	H
	DAD	H
	DAD	H
	DAD	H	;X64
	LXI	D,MSGBF-64	;START
	DAD	D	;CALC LINE ADDR
;MAKE SURE IT'S AN EXISTING LINE
	MOV	A,M
	ORA	A	;EMPTY?
	JZ	ENBADN
	RET		;FROM LINE # INPUT
;
;-----> REENTER A LINE
;
ENRETYP	CALL	ILPRT
	DB	'Retype ',0
	CALL	ENGETL	;GET LINE #
	JZ	ENCOMD	;NO LINE ENTERED
	PUSH	H	;SAVE ADDR
	CALL	ILPRT
	DB	'Line was:',CR,LF,0
	POP	H
	SHLD	ENMAD	;SAVE FOR GETVAR
	CALL	TYPEMCR
	CALL	CRLF
	CALL	GETVARN
	DB	'New line: (C/R to keep old)',CR,LF,0
	DW	ANSWER
02	DW	16	;HELP MSG #
	DB	60	;LEN
	LDA	ANSWER
	CPI	CR
	JZ	ENCOMD
;MOVE LINE
	LHLD	ENMAD
	XCHG
	LXI	H,ANSWER
	MVI	C,CR	;END DELIM
	CALL	MOVEC
	JMP	ENCOMD
;
ENMAD	DW	$-$	;MODIFIED
;
ABORTM	DB	'ABORT',CR
;
	LINK	CBBSRTRV ;NEXT .ASM FILE
