;CBBS V3.5.0 	CBBSSUB2.ASM - NON-DISK ROUTINES # 2
;01/03/82 15:09   
;	LINKS TO CBBSSUB3.ASM
;
;	O O O	O   O	O O	 O O
;	O 	O   O	O   O	O   O
; CBBS	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
;
;MOD LOG: (THRU 3.2 WRITTEN TO "HISTORY")
;
;====> HISTORICAL COMMENTS SINCE 3.3 TO "HISTORY.033"
;
;MODS SINCE 3.5:
;	01/03/81
;Put in label OUTTTY, to facilitate patching it
;out for the test version of cbbs;  also correct
;some missing initializations in reinit routine
;
;		--------
;FOLLOWING COUNTERS TO KEEP SOMEONE FROM
;HANGING UP CBBS INDEFINITELY.  EACH TIME
;KEYIN IS CALLED, A COUNT OF "DELAY1" IS
;SET IN A REGISTER.  STAT IS CALLED 65536
;TIMES THAT COUNT.  WHEN THE COUNT REACHES
;DELAY2, A WARNING MESSAGE IS PRINTED.
;WHEN THE COUNT REACHES 0, THE CALL IS DUMPED.
;
;	N-O-T-E: DOUBLE THESE VALUES IF
;RUNNING 4MHZ.  THE ACTUAL TIMEOUT WILL DEPEND
;UPON THE INSTRUCTION PATH LENGTH THRU YOUR
;BIOS, SO EXPERIMENT WITH THESE VALUES.
;
DELAY1	EQU	50	;COUNT FOR TIMEOUT
DELAY2	EQU	10	;COUNT FOR WARNING
;
;
;-----> MOVE ROUTINE - (HL) TO (DE), LENGTH IN (B)
;
MOVE	MOV	A,M
	STAX	D
	INX	H
	INX	D
	DCR	B
	JNZ	MOVE
	RET
;
;====>	COMP4	COMPARE 4 BYTES
;
COMP4	MVI	B,4	;FALL INTO "COMPR"
;
;-----> COMPARE ROUTINE (HL) VS (DE) LENGTH IN B
;	FIELD (DE) TRANSLATED TO UPPER CASE
;
COMPR	LDAX	D
	CPI	60H	;LOWER CASE?
	JC	COMPNL	;NO
	CPI	7BH
	JNC	COMPNL
	ANI	5FH	;MAKE UPPER CASE
COMPNL	CMP	M
	RNZ
	INX	H
	INX	D
	DCR	B
	JNZ	COMPR
	RET
;
;-----> INLINE PRINT - TYPES MESSAGE (WHICH ENDS
;	W/00H FOLLOWING 'CALL ILPRT').
;	RETURNS TO INSTR FOLLOWING 00H
;
ILPRT	POP	H	;GET MSG ADDR
	CALL	TYPEM0	;TYPE THE MESSAGE
	PCHL		;RET FOLLOWING MESSAGE
;
;---->	ILPRX	IN-LINE PRINT, BUT WITH EXPERT USER
;		MODE FLAG TEST (STOPS AT ":")
;
ILPRX	POP	H
	CALL	TYPEX
	PCHL
;
;-----> TYPE MESSAGE (HL=POINTER, (B) = END OF MSG)
;
TYPEMCR	MVI	B,CR	;CR DELIMITER
	JMP	TYPEM
;
TYPEM0	MVI	B,0	;0 DELIMITER
;
TYPEM	MOV	A,M	;GET CHR
	INX	H
	CMP	B	;END?
	RZ		;..YES
	CALL	NDTYPE	;NO DUP CHAR TYPE
	LDA	CTLCSW
	ORA	A	;DISABLED?
	JNZ	TYPEM	;..YES
	CALL	CTLCKS	;CHECK FOR CTL-C OR S
	JZ	TYPEMS	;GOT ^C
	CPI	'F'-40H	;A FLAG COMMAND?
	JZ	TYPEFLG
	CPI	'M'-40H	;FLAG MISSED ONE?
	JNZ	TYPEM
TYPEFLG	STA	FLAGREQ	;SAVE IT FOR SUMMARY TEST
	JMP	TYPEM
;
;CONTROL-C TYPED - SKIP REST OF MESSAGE
;
TYPEMS	MOV	A,M
	INX	H
	CMP	B	;AT END?
	JNZ	TYPEMS	;LOOP, THEN..
;..FALL INTO CR/LF:
;
;-----> TYPE CR/LF
;
CRLF	MVI	A,CR
	CALL	TYPE
	MVI	A,LF
	JMP	TYPE
;
;-----> INITIALIZATION ROUTINE
;	SETS UP VECTORS TO CBIOS FOR
;	KEYBOARD STATUS TEST, AND KEYBOARD INPUT
;
INIT	LHLD	1	;GET WARM BOOT ADDR
	LXI	D,3	;LENGTH OF EACH JMP
	DAD	D	;TO CONSOLE STATUS
01	SHLD	VCONST+1 ;MODIFY CALL INSTRUCTION
	DAD	D	;TO KEYBOARD INPUT
01	SHLD	VCONIN+1 ;MODIFY JMP INSTRUCTION
	DAD	D	;TO CONSOLE OUT
01	SHLD	VCONOUT+1 ;MODIFY CALL INSTR
04	DAD	D	;TO LIST OUT
;	SHLD	VLIST+1	;MODIFY.
	MVI	A,0DH	;GET C/R
	STA	INBUF	;CLEAR OUT INBUF OF PREV ANS
	STA	FNAME	;SHOW NO NAME ENTERED
;
	IF	TTY
	XRA	A	;GET 0 (EMPTY BUF)
	STA	LOGBUF	;EMPTY BUFFER
	ENDIF
;
	RET
;
;-----> KEYBOARD INPUT ROUTINE WITH NO WAIT.
;	USED FOR CTL-C AND CTL-S CHECK.
;	RETURNS 0 IF NO KEY PRESSED.
;
KEYCHR	CALL	CONST	;GET CONSOLE STAT
	RZ		;NO CHR, RET W/A=0
	CALL	KEYIN	;GET CHR
	RET		;RET W/A=CHAR
;
01 ; START OF -01- MODS TO SAVE REGS
KEYV	PUSH	B
	PUSH	D
	PUSH	H
;
;JMP VECTOR TO CBIOS KEYIN
;
VCONIN	CALL	$-$	;ADDR FILLED IN BY 'INIT'
	POP	H
	POP	D
	POP	B
	RET
01 ;END OF -01- MODS
;
;-----> KEYBOARD INPUT ROUTINE
;THIS DOES NOT DO A NORMAL BDOS CALL, AS THEN THE
;USER WOULD BE ABLE TO CONTROL-C BACK TO CP/M
;WHICH WE DON'T WANT TO HAPPEN
;
KEYIN	call	const	;key pressed?
	ora	a
	jz	keyin
;
;

;;MAKE SURE NO ONE HANGS UP CBBS BY WALKING
;AWAY FROM THEIR TERMINAL.
;
	PUSH	B
KEYW0	MVI	B,DELAY1 ;TIMES 65536 WAITS
KEYWT	CALL	CONST	;KEY PRESSED?
	JNZ	KEYP	;YES.
	DCX	H	;(HL NOT INIT..
	MOV	A,H	;..NO SWEAT)
	ORA	L	;MORE COUNT?
	JNZ	KEYWT	
	MOV	A,B	;TIME TO WARN?
	CPI	DELAY2
	CZ	TIMEWNG	;TYPE WARNI
;
;
;	LDA	PASSFLG
;	ORA	A
;	JZ	KEYW0	;START OVER
;
;TIMEOUT - DUMP THE CALL
;
 IF CLOCK
	CALL	PRETIME
 ENDIF

	LDA	HOLDFLG	;OPERATOR HOLD?
	ORA	A	;	FROM "HOLD"
	JNZ	KEYW0	;	COMMAND?

	CALL	ILPRT
	DB	'CBBS is a single user system.',CR,LF
	DB	'Hope you don''t mind my making it ',CR,LF
	DB	'available for someone else!   Bye.'
	DB	CR,LF,0
	JMP	DISC	;DISCONNECT

;WARN OF TIME RUNNING OUT

TIMEWNG	CALL	CRLF
 IF CLOCK
	CALL	PRETIME
 ENDIF
	CALL	ILPRT
	DB	'..Please continue, ',0
	LXI	H,FNAME
	CALL	TYPEMCR	;PRINT NAME
	CALL	CRLF
	MVI	B,DELAY2
	RET
;
;GOT CHAR - CONTINUE
;
KEYP	POP	B
;
;BUMP COUNT OF CHARACTERS RECEIVED.
;
	LXI	H,NCHRE+6
	CALL	ADD1	;ADD 1 IN ASCII
	CALL	KEYV	;CALL JMP VECTOR
;
;TRANSLATE TO UPPER CASE IF REQ'D
;
	LXI	H,CASE
	CPI	60H
	JC	KINUC
	CPI	7BH
	JNC	KINUC
	ANA	M	;TRANSLATE IF NECESSARY
KINUC	POP	H
;
;CHECK FOR DISCONNECT: CONSOLE IN RETURNS FF IF SO
;
	CPI	0FFH
	RNZ		;NO CARRIER LOSS
;
;IF FLAG SET, DON'T WAIT TO TRY AGAIN.
;
	LDA	CARFLG
	ORA	A
	JNZ	CARLOST
;
;HAVE LOST CARRIER - WAIT 1 SEC, TRY AGAIN.
;TO CATCH MOMENTARY CARRIER LOSS GLITCHES
;
	PUSH	H
	LXI	H,0	;ABOUT 1 SEC DELAY
CARWT	DCX	H
	MOV	A,H
	ORA	A	;DECREMENTED TO 0?
	JNZ	CARWT	;NO
	POP	H
	CALL	KEYV	;CHECK IT
	CPI	0FFH	;STILL NO CARRIER?
	RNZ		;CARRIER BACK - RET W/CHR
	STA	CARFLG	;SHOW CARRIER LOST
;
;IF WE ARE IN THE MIDDLE OF A DISK UPDATE,
;IGNORE THE LOSS OF CARRIER, RETURNING JUST C/R
;
CARLOST	LDA	DKUPSW	;GET SWITCH
	ORA	A
	MVI	A,0DH	;C/R
	RNZ		;RET IF NOT 'KILLABLE'
;
;PRINT DISCONNECT MESSAGE
;(WILL SHOW UP ON LOCAL CONSOLE)
;
	LXI	H,DISCM
PRDIS	MOV	A,M
	ORA	A
	JZ	DISC	;HANG UP
	CALL	TYPE
	INX	H
	JMP	PRDIS
;
;DISCONNECT THE PHONE
;
DISC:
;
01	IF	FAST
01	CALL	FLUSH	;FLUSH BUFFERS
01	ENDIF		;FAST
;
03	IF	NOT TEST
	XRA	A
	OUT	CTLPORT	;TURN OFF MOTOR
;
;CALL THE HANGUP ROUTINE IN:
;CBBSPMMI, CBBSIDS, CBBSHAYS, OR CBBSMODM
;
	CALL	HANGUP
03	ENDIF		;NOT TEST
;
03	IF	TEST
03	JMP	0	;REBOOT CP/M
03	ENDIF		;TEST
;
05	IF	CBBSCHI
05	MVI	A,0CH	;DRIVE D SELECT
05	OUT	0FCH	;NOW NO STEPPER SELECTED
05	ENDIF
;
;	IF	NOT REINIT
;	 /--------------------------\
;	( NOTE FOLLOWING JMP ADDRESS )
;	 \--------------------------/
;
;IN THE ORIGINAL (CHICAGO) CBBS, HARDWARE RING
;DETECT WAS IMPLEMENTED, SO "THE PC WAS PARKED
;IN THE PROM MONITOR" UNTIL RING DETECT RESET
;THE SYSTEM
;
;	JMP	0E000H	;EXIT TO PROM MONITOR
;	ENDIF		;NOT REINIT
;
;---->	COME TO THINK OF IT, IF YOU DO RESET
;YOUR SYSTEM ON A RING, JUST PUT IN SOMETHING LIKE:
;	XXX	JMP	XXX
;
	IF	REINIT
;
;REINITIALIZE VARIABLES, WAIT FOR PHONE TO RING
;
	XRA	A	;GET 0
	STA	CARFLG	;CARRIER LOST FLAG
	STA	DKUPSW	;NO DISK UPDATE
	STA	NULLS	;# OF NULLS
	STA	EXPERT	;NOT EXPERT USER
	STA	NKILATT	;# OF BAD KILLS
	STA	TWITSW	;NOT TWIT
	STA	NONEFLG	;NOT SHORT OUTPUT
	STA	HOLDFLG	;OPERATOR HOLD MODE
;
	INR	A	;MAKE 1
	STA	ECHOFLG	;ECHO MODE
	STA	PASSFLG	;NOT OPERATOR MODE
	STA	BELLF	;TURN ON BELL PROMPT
;
	MVI	A,4	;^K GOES TO "1ST TIME" Q.
	STA	CTLKSW	;DISABLE CTL-K
;
	MVI	A,CCOUNT ;MAX COMMENTS/CALL
	STA	CLEFT
	MVI	A,ECOUNT ;MAX ENTERS/CALL
	STA	ELEFT
;
	MVI	A,8	;RESET DEFAULT
	STA	BSCHAR	;	USER BACKSPACE CHAR
;
	MVI	A,5FH	;TRANSLATE
	STA	CASE	;..TO UPPER CASE
;
	MVI	A,'N'	;RESET COMMENTS..
	STA	COMFLG	;..BUSY FLAG
;BLANK OUT # CHARS TYPED, RECEIVED
	LXI	H,NCHRE	;# ENTERED
	CALL	BLANK7
	LXI	H,NCHRT	;# TYPED
	CALL	BLANK7
;
;WAIT FOR PHONE TO RING 
;
	JMP	RINGWT	;IN CBBS(MODEM).ASM
;
;BLANK 7 BYTES, SUCH AS # CHARS IN AND OUT
;
BLANK7	MVI	B,7
	MVI	A,' '
BL7	MOV	M,A
	INX	H
	DCR	B
	JNZ	BL7
	RET
	ENDIF		;REINIT
;
DISCM	DB	0DH,0AH
	DB	'++Carrier lost, disconnect++'
	DB	0DH,0AH,0
;
;-----> KEYBOARD CONSOLE STATUS ROUTINE
;RETURNS 0FFH IF CHR READY, 0 IF NOT
;
01 ;START OF 01 MODS - TO SAVE REGS
CONST	PUSH	B
	PUSH	D
	PUSH	H
VCONST	CALL	$-$	;ADDR FILLED IN BY 'INIT'
	POP	H
	POP	D
	POP	B
01 ;END OF 01 MODS
	ORA	A	;SET CONDITION
	RET
;
;====>	NDTYPE	TYPES, BUT NOT DUPLICATE CHARS
;
NDTYPE	PUSH	B
	MOV	C,A	;SAVE CHAR
	LDA	NONEFLG	;GET FLAG
	ORI	80H	;SHOW SUPPRESSING
	JMP	TYPE2
;
;SPACE: TYPES A SINGLE SPACE
;
SPACE	MVI	A,' '
;
;-----> CHRACTER OUTPUT ROUTINE
;	TO LOCAL DEVICE AND VIA MODIFIED CBIOS,
;	TO PHONE LINE
;
TYPE	PUSH	B
	MOV	C,A	;SAVE CHAR
	LDA	NONEFLG
	ANI	1
TYPE2	STA	NONEFLG
	MOV	A,C	;RESTORE CHAR
	PUSH	D
	PUSH	H
	CPI	60H	;LOWER CASE CHR?
	JC	TYPEC	;NOT LOWER
01	PUSH	H
	LXI	H,CASE	;GET MASK
	ANA	M	;MAKE UPPER CASE IF MASK=5FH
01	POP	H
;			 (LEAVES AS IS IF MASK=0FFH)
TYPEC	MOV	C,A	;FOR OUTPUT ROUTINE
	CPI	TAB
	JNZ	TYPEV
TYPETAB	MVI	A,' '
	CALL	NDTYPE	;DON'T DOUBLE SPACE IF SUPPRESSED
	LDA	TABCOL
	ANI	7
	JNZ	TYPETAB
	JMP	TYPERET
;
01;START OF MODS: SAVE REGS ON CALL TO BIOS
TYPEV	PUSH	B
	PUSH	D
	PUSH	H
03;MODS: TO SUPPRESS REDUNDANT SPACES AND
;			OTHER GRAPHIC CHARS < '0'
	LXI	H,PREVCHR
	CMP	M	;=PREV CHAR?
	MOV	M,A	;SAVE FOR NEXT TEST
	JNZ	VCONOUT
	CPI	'0'	;CANDIDATE FOR SKIPPING?
	JNC	VCONOUT
	CPI	' '
	JC	VCONOUT	;DON'T KILL 2 BACKSPACES
;TEST IF SUPPRESSING REDUNDANT CHARS
	LDA	NONEFLG
	CPI	81H	;80 = OK TO SKIP, 1 = REQUESTED
	JZ	VCONTP	;	YA, SKIP DUP CHAR
VCONOUT	CALL	$-$	;ADDR FILLED IN BY 'INIT'
04;MODS:
VCONTP	LDA	NONEFLG
	ANI	1	;TURN OFF PERMISSION
	STA	NONEFLG
;	LDA	PRINTSW	;PRINT COMMAND EXECUTED?
;	ORA	A
;VLIST	CNZ	$-$	;CALL BIOS LIST IF SO
04;END
;
03;END
04;MODS:	TO SLOW DOWN TYPING DURING TESTING
;		OPERATOR "SLOW" COMMAND SLOWS THINGS DOWN
TYPDLY	LXI	H,1 ;THIS VALUE MODIFIED BY "SLOW" COMMAND
TYPDLP	DCX	H
	MOV	A,H
	ORA	L
	JNZ	TYPDLP
04;END
	POP	H
	POP	D
	POP	B
01;END OF MODS
;
;UPDATE COLUMN USED IN TAB EXPANSION
;
	MOV	A,C
	CPI	CR
	JNZ	TYPENCR
	MVI	A,0
	STA	TABCOL
	JMP	TYPEBC
;
TYPENCR	CPI	8	;VIDEO BACKSPACE?
	JNZ	TYPENBS
	LDA	TABCOL
	DCR	A
	STA	TABCOL
	JMP	TYPEBC
;
TYPENBS	CPI	' '	;CTL CHAR?
	JC	TYPEBC	;..NO CHANGE IN COL
	LDA	TABCOL
	INR	A
	STA	TABCOL
;
;BUMP COUNT OF CHRACTERS TYPED
;
TYPEBC	LXI	H,NCHRT+6
	CALL	ADD1
;
	IF	TTY	;HAVE LOG TTY?
	CALL	CKTTY	;SEE IF ANY CHRS TO GO
	ENDIF
;
;CHECK IF LINEFEED, AND IF SO, SEND NULLS
;IF REQUESTED
;
	MOV	A,C	;GET CHR
	CPI	0AH
	CZ	DONUL	;DO NULLS
TYPERET	POP	H
	POP	D
	POP	B
	RET
;
;ROUTINE TO SEND OUT NULLS FOLLOWING CR/LF
;
DONUL	LDA	NULLS	;GET COUNT
	INR	A	;MAKE 0 INTO 1
	MOV	B,A
;
;MAY ENTER HERE W/NULL COUNT + 1 IN B
;
NULLP	DCR	B	;END OF NULLS?
	RZ		;..YES
	XRA	A	;GET NULL
	CALL	TYPE	;TYPE IT
	JMP	NULLP
;
	IF	TTY
;
;ROUTINE TO ASYNCHRONOUSLY LOG DATA TO A TTY.
;ONLY DATA KEYED IN IS LOGGED. 
;
;THIS ROUTINE IS ASYNCHRONOUS TO ALLOW A
;110 BAUD TTY TO LOG EVEN THO SOMEONE MIGHT
;BE KEYING IN FASTER, EITHER MANUALLY, OR
;FROM A PROGRAM.  IF THE LOGGING TTY GETS
;256 CHARS BEHIND, THEN IT JUST THROWS 256
;CHARS AWAY AND CONTINUES.  L/F AUTOMATICALLY
;SENT AFTER C/R
;
LOG	PUSH	H	;SAVE HL
	LHLD	TTYSTP	;GET BUFFER POINTER
	CPI	CR
	JNZ	CKSTOR	;NOT C/R, STORE
;IF COLUMN > 60 THEN STORE C/R, OTHERWISE '/'
	LDA	COL
	CPI	60
	MVI	A,CR
	JNC	CKSTOR
;COL < 60, STORE '/' INSTEAD
	MVI	A,'/'
CKSTOR	MOV	M,A	;STORE CHR
	INR	L	;BUMP, STAY W/IN 256 BYTES
	MVI	M,0	;END OF BUFFER POINTER
	SHLD	TTYSTP
	PUSH	PSW	;SAVE CHR
	CALL	CKTTY	;TYPE BUFFERED CHARS
	POP	PSW	;GET CHAR FOR CR TEST
;BUMP COL, OR SET =0 IF C/R
	LXI	H,COL
	INR	M
	CPI	CR
	JNZ	CKCOL
	MVI	M,0	;RESET
;CHECK IF COL>70, C/R IF SO
CKCOL	MOV	A,M	;GET COL
	CPI	70
	POP	H
	RC		;RET IF < 70
	MVI	A,CR
	JMP	LOG	;STORE C/R THIS TIME
;
;CHECK IF TTY READY FOR OUTPUT.  NO REGS SAVED
;
CKTTY	LHLD	TTYLDP	;GET LOAD POINTER
	MOV	A,M	;GET CHR
	ORA	A	;END OF BUFF?
	RZ		;YES, RET
;SEE IF TTY READY
	IN	TTYSP
	ANI	TTYST
;
;-----> NOTE YOU MIGHT HAVE TO CHANGE FOLLOWING TO RNZ
;
	RZ		;TTY NOT READY
	MOV	A,M	;GET CHR
OUTTTY	OUT	TTYDP	;OUTPUT IT	ADDED LABEL 1/3/82
	CPI	CR	;C/R?
	JNZ	TTYNCR	;NO.
;GOT C/R - STORE LINE FEED FOR NEXT TIME
	MVI	M,LF
;		PMMI
;	    OR	 CBBSMODM	SERIAL
;
;	O O O	O   O	O O	 O O
;	O 	O   O	O   O	O   O
; CBBS	O O O	O   O	O O	   O 	.ASM
;	    O	6 L/F'S
;NEXT 15 LINES ADDED, TO PAGE EJECT PRINTER
	CPI	LF
	JNZ	TTYNLF
	LDA	TTYLCT	;GET LINE COUNT
	INR	A
	STA	TTYLCT
	CPI	60
	JNZ	TTYNLF	;NOT AT 60
;LINE COUNT IS AT 60, STORE 6 LF'S
	MVI	A,256-6 ;TRICK SO ASM WON'T GLITCH
	STA	TTYLCT	;SET LINE COUNT = -6
TTYSLF	DCR	L	;BACK UP 1
	MVI	M,LF	;STORE LF
	INR	A
	JNZ	TTYSLF
	ENDIF		;EJECT AND TTY
;
	IF	TTY
TTYNLF	SHLD	TTYLDP	;SAVE LOAD POINTER
	RET
	ENDIF		;TTY
;
;BUMP ASCII COUNT FIELD (HL POINTS TO UNITS DIGIT)
;(SUCH AS # OF CHARS KEYED, ETC)
;
ADD1	MOV	A,M	;GET NUMBER (OR ' ')
	ORI	'0'	;TURN ' ' INTO '0'
	INR	A	;ADD 1
	MOV	M,A
	CPI	'9'+1
	RC		;RETURN IF 0-9
	MVI	M,'0'	;CARRY
	DCX	H	;NEXT HIGHER DIGIT
	JMP	ADD1
;
;DECR ASCII COUNT FIELD (HL POINTS TO UNITS DIGIT)
;(USED FOR # OF ACTIVE MESSAGES UPON KILL)
;
SUB1	MOV	A,M	;GET NUMBER (OR ' ')
	ORI	'0'	;TURN ' ' INTO '0'
	DCR	A	;SUB 1
	MOV	M,A
	CPI	'0'-1	;TIME TO BORROW?
	RNZ		;RETURN IF 0-9
	MVI	M,'9'	;BORROW
	DCX	H	;NEXT HIGHER DIGIT
	JMP	SUB1
;
;COUNT CHRACTERS IN FIELD
;(USED TO SEE THAT 1STNAME+LASTNAME < 21 CHRS
;
COUNTC0	MVI	B,0	;INIT COUNT
COUNTC	MOV	A,M
	CPI	CR	;END?
	MOV	A,B	;GET COUNT
	RZ
	INR	B	;INCR COUNT
	INX	H
	JMP	COUNTC
;
;IDS AND PMMI CAN TAKE VARIABLE BAUD RATE,
;SO 'A' (ALTER BAUD RATE) IS USED TO SELECT
;IT AS DESIRED.  INPUT IS A DECIMAL RATE.
;
	IF	IDS OR PMMI
;
;A:	ALTER BAUD RATE COMMAND
;
ALTBAUD	CALL	GETVAR
	DB	'Baud rate: (65-600) '
	DB	'(C/R to leave as is)',0
	DW	ANSWER
02	DW	00	;HELP MSG #
	DB	3
	LDA	ANSWER
	CPI	CR
	JZ	FUNCT	;NO ANSWER
	CALL	GETNUM	;VALIDATE, CONV BINARY
	JC	ALTBAUD	;INVALID, RE-ASK
;
;CALCULATE THE VALUE TO OUTPUT:
;
;	RATE = 250000/16/BAUD RATE
;
;	DIVIDE BY REPETITIVE SUBTRACTION
;	------
;COMPLEMENT THE BAUD RATE
;
	MOV	A,H	;GET HI
	CMA		;COMPLEMENT
	MOV	D,A	;SAVE
	MOV	A,L	;GET LO
	CMA		;COMPLEMENT
	MOV	E,A	;SAVE
	INX	D	;DE=2'S COMPLEMENT
;DIVIDE
	LXI	H,15625	;=250000/16 
	LXI	B,-1	;INIT QUOTIENT
;
DIVLP	INX	B	;BUMP QUOTIENT
	DAD	D	;'SUBTRACT'
	JC	DIVLP	;LOOP 'TILL DONE
;
;VALIDATE THE RESULT
;
	MOV	A,B	;CAN'T HAVE >255
	ORA	A
	JNZ	BADRATE
	MOV	A,C	;BAD IF >700
	CPI	22	;22 IS 700 BAUD
	JC	BADRATE
	PUSH	B	;SAVE VALUE (IN C)
	CALL	ILPRT
	DB	'OK.  Press any key '
	DB	'to continue at that speed.'
	DB	CR,LF,0
	POP	B
;
;JMP TO PMMI OR IDS ROUTINE TO SET RATE.
;BINARY VALUE TO OUTPUT IS IN C.
;
	JMP	SETBAUD
;
;INVALID BAUD RATE
;
BADRATE	CALL	ILPRT
	DB	'++Invalid baud rate++',CR,LF,0
	JMP	FUNCT
	ENDIF		;PMMI OR IDS
;
	LINK	CBBSSUB3 ;TO NEXT .ASM FILE
