title	ldebiocs Debug I/O control stuff
;	SCCSID = @(#)ldebiocs.asm	11.3 89/03/16

.xlist
.xcref
include ldebequ.inc
.list
.cref

include ldebseg.inc

DBDATA	segment

	extrn	_pTXT:word
	extrn	_lbf:byte

BACMES		db	32,8+80H

DBDATA	ends

DBCODE	segment

	public	_IN, _chkctlc, _OUT, _OUTpc, _RPRBUF
	public	_CRLF, _BLANK, _TAB, _INBUF
	public	_ScanP, _SkipB, _GetChr, _GetChrI
	public	_PRINTMES, _HEX, _OUTSI, _OUTDI, _OUT16
	public	_DIGIT, _BACKUP

	extrn	_PERR:near
	extrn	inchar:near
	extrn	putchar:near


; Console input of single character

_IN proc
in1:	call	inchar
	jz	in1
	jmp	_OUT
_IN endp


;**	_chkctlc - Check console input for control C character
;
;	EXIT	Z flag set if control C character was read

_chkctlc:
	push	ax
	call	inchar
	cmp	al,3
	pop	ax
	ret

; Console output of character in AL. No registers affected but bit 7
; is reset before output.

_OUT:	push	bx			; output the character in lower case
	xor	bx,bx
	jmp	short out00

_OUTpc:	push	bx			; output the character, preserve case
	mov	bx,1
out00:	push	ax
	and	al,7fh
	cmp	al,7fh
	jnz	out10
	mov	al,8			; DELETE same as backspace
out10:	or	bx,bx
	jnz	short out20
	cmp	al,"A"
	jb	short out20
	cmp	al,"Z"
	ja	short out20
	or	al,20h
out20:	call	putchar
	cmp	al,8
	jnz	out90
	mov	al," "
	call	putchar
	mov	al,8
	call	putchar
out90:	pop	ax
	pop	bx
	ret

ESC_	=   27				    ;esc key

RBUFIN:
	PUSH	AX
	PUSH	DI
	PUSH	ES
	PUSH	CS
	POP	ES
RBUFIN0:
	MOV	byte ptr [_lbf.lbcnt],0
	MOV	DI,OFFSET ds:_lbf.lbuff
FILLBUF:
	CALL	_IN
FILLBF0:
	CMP	AL,CR
	JZ	BDONE
	CMP	AL,8
	JZ	ECHR
	CMP	AL,7FH
	JZ	ECHR
	CMP	AL,ESC_
	JZ	CANBUF
	CMP	byte ptr [_lbf.lbcnt],BUFLEN
	JAE	BFULL
	CLD
	STOSB
	INC	byte ptr [_lbf.lbcnt]
	JMP	SHORT FILLBUF
BDONE:
	CLD
	STOSB
	POP	ES
	POP	DI
	POP	AX
	RET
BFULL:
	MOV	AL,8
	CALL	_OUT
	MOV	AL,7
	CALL	_OUT
	JMP	SHORT FILLBUF
ECHR:
	CMP	DI,OFFSET ds:_lbf.lbuff
	JZ	FILLBUF
	DEC	DI
	DEC	byte ptr [_lbf.lbcnt]
	JMP	SHORT FILLBUF
CANBUF:
	MOV	CX,DI
	SUB	CX,OFFSET ds:_lbf.lbuff
CANBFL:
	MOV	AL,8
	CALL	_OUT
	LOOP	CANBFL
	JMP	RBUFIN0

_RPRBUF:
	PUSH	AX
	PUSH	SI
	MOV	SI,DX
PLOOP:
	CLD
	LODSB
	CMP	AL,"$"
	JZ	PRTDONE
	CALL	_OUTpc
	JMP	SHORT PLOOP
PRTDONE:
	POP	SI
	POP	AX
	RET


;;;;;;;;;;;;;;;;;;;


; Get input line. Convert all characters NOT in quotes to upper case.

_INBUF:
	CALL	RBUFIN
	MOV	SI,OFFSET ds:_lbf.lbuff
	MOV	DI,OFFSET ds:_lbf.lbuff
CASECHK:
	LODSB
	CMP	AL,'a'
	JB	NOCONV
	CMP	AL,'z'
	JA	NOCONV
	ADD	AL,"A"-"a"		; Convert to upper case
NOCONV:
	STOSB
	CMP	AL,CR
	JZ	INDONE
	CMP	AL,'"'
	JZ	QUOTSCAN
	CMP	AL,"'"
	JNZ	CASECHK
QUOTSCAN:
	MOV	AH,AL
KILLSTR:
	LODSB
	STOSB
	CMP	AL,CR
	JZ	INDONE
	CMP	AL,AH
	JNZ	KILLSTR
	JMP	SHORT CASECHK

INDONE:
	MOV	SI,OFFSET ds:_lbf.lbuff
	MOV	[_pTXT],SI

; Output CR/LF sequence

_CRLF:
	MOV	AL,CR
	CALL	_OUT
	MOV	AL,LF
	JMP	_OUT

; Physical backspace - blank, backspace, blank

_BACKUP:
	MOV	SI,OFFSET ds:BACMES

; Print ASCII message. Last char has bit 7 set

_PRINTMES:
	LODS	CS:byte ptr [SI]	; Get char to print
	CALL	_OUT
	SHL	AL,1			; High bit set?
	JNC	_PRINTMES
	RET

; Incr _pTXT if next non-blank character = [AH]
; else syntax error.

SynCheck:
	CALL	_GetChrI		; Get first non-blank & incr _pTXT
	CMP	AL,AH			; must match,
	JE	EOLCHK			; Brif match
	JMP	_PERR			; else syntax error

; Scan for parameters of a command

_ScanP:
	CALL	_GetChr 		; Get first non-blank
	CMP	AL,","			; One comma between params OK
	JNE	EOLCHK			; If not comma, we found param
_SkipB:
	INC	[_pTXT] 		; Skip over comma

; Re-get current character skipping over
; blanks only.

_GetChr:
	CALL	_GetChrI		; Get first non-blank & incr _pTXT
	JZ	GetChx
	DEC	SI			; Back to first non-blank
	MOV	[_pTXT],SI
GetChx:
	RET

; Get next non-blank character, advance _pTXT except for ;

_GetChrI:
	MOV	SI,[_pTXT]
	CLD
GetChr0:
	LODSB
	CMP	AL," "
	JZ	GetChr0
	CMP	AL,9
	JZ	GetChr0
	MOV	[_pTXT],SI
	CMP	AL,";"			;Don't advance _pTXT
	JE	GetChd			; beyond eos
	CMP	AL,CR
	JNE	EOLCHK
GetChd:
	DEC	SI			; Back to first non-blank
	MOV	[_pTXT],SI
EOLCHK:
	CMP	AL,";"			;End of command
	JE	EOLCHX			; if semicolon
	CMP	AL,CR
EOLCHX:
	RET

; Print the hex address of DS:SI

_OUTSI:
	MOV	DX,DS			; Put DS where we can work with it
	CALL	_OUT16			; Display segment
	MOV	AL,":"
	CALL	_OUT
	MOV	DX,SI
	JMP	SHORT _OUT16		; Output displacement

; Print hex address of ES:DI
; Same as _OUTSI above

_OUTDI:
	MOV	DX,ES
	CALL	_OUT16
	MOV	AL,":"
	CALL	_OUT
	MOV	DX,DI

; Print out 16-bit value in DX in hex

_OUT16:
	MOV	AL,DH			; High-order byte first
	CALL	_HEX
	MOV	AL,DL			; Then low-order byte

; Output byte in AL as two hex digits

_HEX:
	MOV	AH,AL			; Save for second digit
; Shift high digit into low 4 bits
	PUSH	CX
	MOV	CL,4
	SHR	AL,CL
	POP	CX

	CALL	_DIGIT			; Output first digit
	MOV	AL,AH			; Now do digit saved in AH
_DIGIT:
	AND	AL,0FH			; Mask to 4 bits
; Trick 6-byte hex conversion works on 8086 too.
	ADD	AL,90H
	DAA
	ADC	AL,40H
	DAA
	JMP	_OUT

; Output one space

_BLANK:
	MOV	AL," "
	JMP	_OUT

; Output the number of blanks in CX

_TAB:
	CALL	_BLANK
	LOOP	_TAB
	RET

DBCODE	ends

	end
