; Doug's Programming Language  -- DPL, Version 2.22
; Copyright (c) 1988 Douglas S. Cody, All rights reserved.
;------------------------------------------------
; EDITM  -- EDIT A MASK OF CHARACTERS
;
; Entry conditions:
;	AX points to the mask string
;	BX points to the target string
; Exit conditions:
;	Target string holds the input
;
SUBPGM	EDITM
;
INTEGER	ROW			; HOLDS THE CURRENT VIDEO ROW POSITION
INTEGER COL			; HOLDS THE CURRENT VIDEO COLUMN POSITION
;
ATTR	DB	0		; HOLDS THE MOST RECENT VIDEO ATTRIBUTE
;
BEGIN	EDITM
	EXTRN	_STRLEN:NEAR
;
	PUSH	ES
	PUSH	SI
	PUSH	DI
;
	PUSH	DS
	POP	ES
	MOV	DI,BX			; DI POINTS TO THE TARGET STRING
	MOV	SI,AX			; SI POINTS TO THE MASK
	CALL	_STRLEN			; CX HOLDS THE MASK LENGTH
	PUSH	CX			; + 4
	PUSH	DI
	ADD	DI,CX			; POINT TO THE END OF THE STRING
	SUB	AL,AL			; & SET THE NEW TERMINATOR
	STOSB
;
	MOV	AH,0FH
	INT	10H
	MOV	AH,03
	INT	10H
	SUB	AH,AH
	MOV	AL,DH			; SAVE THE ROW
	MOV	[ROW],AX
	MOV	AL,DL
	MOV	[COL],AX		; SAVE THE COLUMN
;
	POP	DI			; GET THE TARGET STRING BACK
	SUB	AX,AX			; AX = THE STORED COUNT
	PUSH	AX			; + 2
	PUSH	BP
	MOV	BP,SP			; FRAME IT...
;
; PERFORM THE INPUT...
;
EDM_00:
	MOV	AH,08			; GET THE ATTRIBUTE
	INT	10H
	MOV	[ATTR],AH
;
	MOV	AL,20H
	CMP	[SI],AL			; SPACE?
	JZ	EDM_05S			; YES, MOVE TO THE NEXT NON-BLANK
;
EDM_05:
	INKEY	,WAIT
	CMP	AL,0			; GOOD CHARACTER?
	JZ	EDM_05			; NO, CONTINUE WAITING
;
	CMP	AL,08			; BACKSPACE?
	JZ	EDM_10			; YES, GO ATTEMPT A BACKSPACE
;
	CMP	AL,0DH			; CARRIAGE RETURN?
	JZ	EDM_15			; YES, EXIT HOME
;
	CMP	WORD PTR [BP+4],0	; ARE WE OUT OF ROOM?
	JZ	EDM_05			; YES, TOSS THE CHARACTER
;
	CALL	VALIDATE		; CHECK FOR PROPER INPUT
	JC	EDM_05			; TOSS IT IF NOT RIGHT
;
EDM_05S:
	STOSB				; STORE IN THE TARGET STRING
;
	MOV	CX,01			; DO JUST ONE CHARACTER
	MOV	BL,[ATTR]		; GET THE ATTRIBUTE
	MOV	AH,09
	INT	10H			; GO SEND IT TO THE SCREEN
;
	DEC	WORD PTR [BP+4]		; ONE LESS TO GO...
	INC	WORD PTR [BP+2]		; ONE ADDED TO THE TARGET
	INC	SI			; MOVE TO THE NEXT CHARACTER
	INC	[COL]
	CURSOR	ROW,COL			; MOVE THE CURSOR
	JMP	EDM_00			; CONTINUE THE INPUT...
;
; BACKSPACE PROCESSING...
;
EDM_10:
	CMP	WORD PTR [BP+2],0	; ARE WE AT THE START?
	JZ	EDM_05			; YES, TOSS THE BACKSPACE
;
	DEC	WORD PTR [BP+2]		; SUBTRACT ONE FROM THE STORAGE COUNT
	INC	WORD PTR [BP+4]		; ADD ONE TO THE AVAILABLE COUNT
	DEC	SI			; BACKSTEP THE MASK POINTER
	DEC	DI			; BACKSTEP THE TARGET POINTER
	DEC	[COL]			; MOVE THE CURSOR
	CURSOR	ROW,COL
	CMP	BYTE PTR [SI],20H	; IS THE CHARACTER A SPACE?
	JZ	EDM_10			; YES, SKIP IT
	JMP	EDM_00			; NO, GO BACK TO INPUTTING...
;
EDM_15:
	POP	BP			; RESTORE ALL
	ADD	SP,4			; FLUSH THE TWO WORDS
;
	POP	DI
	POP	SI
	POP	ES
	RET
;
;
;----------------------------------------
; VALIDATE THE CHARACTER FROM INPUT
;
; Entry conditions:
;	AL holds the character
; Exit conditions:
;	CARRY set   = bad character
;	CARRY clear = good character
;	BX modified
;
VALIDATE	PROC	NEAR
	CMP	BYTE PTR [SI],'X'	; ANY INPUT OKAY?
	JZ	VAL_GOOD		; YES, KEEP IT...
;
	MOV	BL,0DFH			; CONVERT TO UPPERCASE
	AND	BL,AL			; BL WILL HOLD THE UPPERCASE CHARACTER
;
	CMP	BYTE PTR [SI],'A'	; ALPHA INPUT ONLY?
	JNZ	VAL_05			; NO, CONTINUE ON...
	CMP	BL,'A'			; LOWER THAN AN A?
	JB	VAL_BAD			; YES
	CMP	BL,'Z'			; GREATER THAN A Z?
	JA	VAL_BAD			; YES, YES FLUSH IT
	JMP	SHORT VAL_GOOD		; NO, KEEP IT...
;
VAL_05:
	CMP	BYTE PTR [SI],'B'	; BINARY INPUT?
	JNZ	VAL_10			; NO, CONTINUE ON...
	CMP	AL,'0'			; ZERO?
	JZ	VAL_GOOD		; YES
	CMP	AL,'1'			; ONE?
	JZ	VAL_GOOD		; YES
	JMP	SHORT VAL_BAD		; NO, FLUSH IT...
;
VAL_10:
	CMP	BYTE PTR [SI],'D'	; DECIMAL INPUT?
	JNZ	VAL_15			; NO, CONTINUE ON...
	CMP	AL,'0'			; LESS THAN ZERO?
	JB	VAL_BAD			; YES
	CMP	AL,'9'			; GT 9?
	JA	VAL_BAD			; YES
	JMP	SHORT VAL_GOOD		; NO, KEEP IT...
;
VAL_15:
	CMP	BYTE PTR [SI],'H'	; HEXADECIMAL INPUT?
	JNZ	VAL_20			; NO, CONTINUE ON...
	CMP	AL,'0'			; LESS THAN ZERO?
	JB	VAL_BAD			; YES
	CMP	AL,'9'			; GE 9?
	JLE	VAL_GOOD		; YES, IT RANGES FROM 0 TO 9
	CMP	AL,'A'			; LESS THAN 'A'?
	JB	VAL_BAD			; YES, EXIT BAD
	CMP	AL,'F'			; GT 'F'
	JA	VAL_BAD			; YES
	JMP	SHORT VAL_GOOD		; NO, KEEP IT...
;
VAL_20:
	CMP	BYTE PTR [SI],'O'	; OCTAL INPUT?
	JNZ	VAL_BAD			; NO, CONTINUE ON...
	CMP	AL,'0'			; LESS THAN ZERO?
	JB	VAL_BAD			; YES
	CMP	AL,'7'			; GT 7?
	JA	VAL_BAD			; YES
;
VAL_GOOD:
	CLC				; CARRY CLEAR = GOOD
	RET
;
VAL_BAD:
	STC				; CARRY SET = BAD
	RET

VALIDATE	ENDP
;
ENDPGM	EDITM
;
