Compucolor.org – Virtual Media

Listing of file='PATCH.SRC;02' on disk='vmedia/comm_pgms-sideA-sector.ccvf'

;	THE CHEAP LOWER CASE OPTION   DATA CHIP #18 JUL/AUG 80
;
;	A few words about the functions:
;
;     1	Lower Case Translation.  Lower case letters typed into
;	the machine appear on the screen in a user-selectable
;	color, which can be different from the upper case
;	characters.  Inside the machine in the string variable,
;	there are still upper and lower case characters, just
;	as they were typed, but on the screen there are only
;	upper.  Print the string, and the results are as you
;	typed (if your printer displays lower case).  The
;	function operates by periodically scanning through
;	screen memory looking for lower case characters,
;	translating them to upper case characters and changing
;	their CCI codes.  The routine can also be called
;	directly, so translation can be done after PRINT
;	statements fill the screen with graphics.  (The
;	periodic routine only operates during BASIC INPUT
;	statements.  It stops with the terminating C/R so
;	as not to waste compute time.)
;
;     2	Control Character Deletion.  All control characters
;	(those with values 0<=char<=31 decimal) are ignored,
;	except cursor left, erase line and C/R.  A filter
;	routine is interposed between the CCII keyboard routine
;	and BASIC, which looks for and drops the offensive
;	characters.
;
;     3	Line Length Limiting.  By passing a value representing
;	the maximum number of characters permitted in an INPUT,
;	the filter routine mentioned above checks the number of
;	characters typed, and permits no more than the desired
;	number to be INPUT.  Excessive characters are ignored.
;
;	Each function or their combination is selected by
;	passing a code to the routine in the format:
;
;		1a00 0bcd	(binary) where:
;
;		a when 1 indicates a straight call to the
;			 lower case translation routine
;		b when 1 indicates that the length limit
;			 function should be active
;		c when 1 indicates that control characters
;			 are to be discarded
;		d when 1 indicates that lower case translation
;			 is desired
;
;	When d is requested, the CCI (multiplied by 256)
;	accompanies the control code.  a only works when d has
;	been previously selected, i.e., one CALL must be made
;	with "d" set, then another requesting "a".  When the
;	length limit function is active, lengths are passed
;	immediately prior to the INPUT statement by a CALL
;	statement with the desired length as an argument.
;
;	For those of you who may not be familiar with binary
;	notation, construct the control code by adding together
;	the following values for the options desired:
;
;		128	always add this in for control codes.
;		 64	a option
;		  4	b option
;		  2	c option
;		  1	d option
;
;
;
BASIC	EQU	4B0H	;BASIC INPUT ROUTINE
BUFEND	EQU	80DEH	;CURRENT END OF BASIC INPUT BUFFER
KEYBRD	EQU	81DFH	;KEYBOARD INPUT FLAG
SAVE	EQU	3FD0H	;ROM ROUTINE TO SAVE REGISTERS
;
;
	ORG	0BF20H	;HIGH END OF 16K CCII
;
;	SET UP LINKAGES WHEN RUN
;
START:	PUSH	PSW
	PUSH	H
	LXI	H,CALLRTN
	SHLD	8203H	;USER CALL ROUTINE JUMP VECTOR
	LXI	H,CHARIN
	SHLD	81C6H	;USER INPUT FLAG JUMP VECTOR
	LXI	H,TIMER2
	SHLD	81C9H	;USER TIMER #2 JUMP VECTOR
	MVI	A,0C3H	;JMP OP CODE
	STA	8202H	;USER CALL ROUTINE JUMP VECTOR
	STA	81C5H	;USER INPUT FLAG JUMP VECTOR
	STA	81C8H	;USER TIMER #2 JUMP VECTOR
	POP	H
	POP	PSW
	MVI	B,0	;TELL FCS THAT ALL IS WELL
	RET
;
;
TIMER:	DB	0	;TIMER VALUE
LENGTH:	DB	0	;MAX READ LENGTH
SELECT:	DB	0	;FUNCTION SELECTOR
;
CCI:	DB	0	;CCI CODE FOR LOWER CASE
;
;	TIMER 2 ROUTINE
;
;	STARTED BY CALL ROUTINE
;	STOPS WHEN ZERO FOUND IN TIMER
;
TIMER2:	PUSH	PSW
	PUSH	H
	LDA	SELECT	;DO WE WANT LOWER->UPPER CASE XLATION?
	ANI	01H	;01 SELECTS LOWER->UPPER
	JZ	RETIME
	LXI	H,6000H
	EI
LOOP:	MOV	A,M
	CPI	97	;LOWER CASE A
	JC	NEXT
	CPI	123	;LOWER CASE Z
	JNC	NEXT
	ANI	0DFH	;MAKE UPPER CASE
	MOV	M,A
	INX	H	;POINT TO CCI
	LDA	CCI	;GET USER LOWER CASE CCI CODE
	MOV	M,A
	JMP	NEXT2
NEXT:	INX	H
NEXT2:	INX	H
	MOV	A,H
	CPI	70H	;AT END OF SCREEN BUFFER?
	JNZ	LOOP	;NO
RETIME:	LDA	TIMER
	CPI	0
	JZ	NOTIME	;SKIP IF TIMER NOT TO BE SET
	OUT	10	;RESTART TIMER
	MVI	A,31	;USER INPUT VECTOR
	STA	KEYBRD	;MAKE SURE OUR VECTOR IS THERE
NOTIME:	POP	H
	POP	PSW
	RET
;
;	CHARACTER INPUT INTERRUPT ROUTINE
;
;	ENTERED THRU "31" LINKAGE WHEN CHARACTER IS TYPED
;	TIMER 2 STOPPED WITH C/R
;	4B0H IS BASIC INPUT ROUTINE
;
CHARIN:	MOV	M,A	;STORE CHARACTER
	MOV	A,E	;GET CURRENT INPUT CHARACTER
	CPI	26	;CURSOR LEFT	OK
	JZ	BASIC
	CPI	11	;ERASE LINE	OK
	JZ	BASIC
	CPI	13	;C/R		OK	END
	JNZ	CHECK
	LXI	H,TIMER
	MVI	M,0	;CANCEL TIMER
	JMP	BASIC
CHECK:	CPI	32	;ANYTHING LESS THAN SPACE DISCARDED
	JNC	CHKLEN
	LDA	SELECT
	ANI	02H	;SELECT CONTROL CHARACTER DISCARD
	JZ	CHKLEN
	RET		;DISCARD CONTROL CHARACTERS
CHKLEN:	LHLD	BUFEND	;POINTER TO CURRENT END OF BASIC INPUT
	LDA	SELECT
	ANI	04H	;SELECT CHECK LENGTH
	JZ	LEAVE
	PUSH	H
	MOV	A,L
	LXI	H,LENGTH
	SUB	M
	POP	H
	RZ		;IGNORE IF MORE THAN "LENGTH"
LEAVE:	MOV	A,E
	JMP	BASIC
;
;	CALL ROUTINE
;
;	ROUTINE CALLED FROM BASIC
;	128 AND > IS SELECT CODE
;	<128 IS LENGTH
;
CALLRTN:CALL	SAVE	;SAVE REGISTERS
	MVI	A,31	;USER INPUT VECTOR
	STA	KEYBRD	;FORCE INPUT TO COME THROUGH US
	MOV	A,E
	ANI	128
	JZ	SETL
	MOV	A,E
	STA	SELECT	;CALLED WITH SELECT CODE IN E
	MOV	A,D
	STA	CCI	;SAVE CCI CODE TO USE FOR LOWER CASE
	MOV	A,E
	ANI	40H
	JZ	STARTT	;DO 1 TRANSLATION IF REQUESTED
	CALL	TIMER2
	RET
SETL:	MVI	A,46H	;ADJUST FOR ADDRESS COMPARE
	ADD	E
	STA	LENGTH
STARTT:	MVI	A,5	;SET TIMER FOR 5*64 MICROSECONDS
	STA	TIMER
	OUT	10
	RET
;
	END	START