filename RD013086.ULA (was ONSCR-UL.ASM)
;******************************************
;
;	ONSCR-UL.ASM
;
;	ON-SCREEN UNDERLINING 
;
;	see ONSCR-UL.DOC for operation
;
;	Robert E. Daniels
;	December 5, 1985
;
;..........................................
;	
;EQUATES
;
wboot	equ	00h	;warm boot
bdos	equ	05h	;BDOS entry point
conio	equ	06h	;direct console input/output:
input	equ	0ffh	;input if 0ffh is loaded in reg. E 
			;output if anything else is in E 
bksp	equ	08h	;backspace, i.e. "<-" left arrow key
lf	equ	0ah	;linefeed
cr	equ	0dh	;carriage return
switch	equ	13h	;^S, used as toggle switch for 
			;underlining ON/OFF 
zap	equ	1ah	;^Z, used here as exit signal 
rubchr	equ	1fh	;^- or destructive backspace in WS
space	equ	20h	;blank space character
;..........................................
;
	org 	100h
;
;SET UP LOCAL STACK
;
	lxi	h,0		;clear HL
	dad	sp		;add stack pointer to HL
	shld	oldsp		;save it to memory
	lxi	sp,stktop	;set up new program stack
;
;CREATE TOGGLE, SET TO NO UNDERLINING
;
	ora	a		;set carry flag to 0
				;the carry flag serves as toggle
	push	psw		;save this value
;
;GET INPUT, TEST FOR SPECIAL CHARACTERS, ACT ON THEM
;
start	mvi	e,input		;do input	
	mvi	c,conio		;using function #6
	call	bdos		;and get first/next character 
				;from keyboard
;
test1	cpi	0		;if no input, 
	jz	start		;start over
				;this is necessary because once
				;in underlining mode 0 is otherwise 
				;converted to 80h and printed 
				;with each cycle, filling screen
;
test2	cpi	zap		;is input ^Z
	jz	alldone		;if so, bail out
;
test3	cpi	cr		;is input a carriage RETURN?
	jnz	test4		;if NOT, go to next test
	call	print		;if so, send it to screen
	mvi	a,lf		;along with a linefeed
	call	print		;to screen
	jmp	start		;get the next character
;
test4	cpi	rubchr 		;is input ^-?
	jnz	test5		;if NOT, go to next test
	cz	rubout		;else go to rubout subroutine
	jmp	start		;get the next character
;
test5	cpi	bksp		;is input a backspace?
	jnz	test6		;if NOT, go to next test
	call	print		;if so, send it to screen
	jmp	start		;get the next character
;
test6	cpi	space		;is input a blank space?
	jnz	test7		;if NOT, go to next test
	call	print		;if so, send it to screen
	jmp	start		;get the next character
;
;CHECK FOR UNDERLINING
;
test7	mov	b,a		;first save character value to B
				;because recalling the toggle 
				;flag in the Program Status Word 
				;will also step on register A
	cpi	switch		;is the character ^S
	jnz	same		;if NOT keep toggle unchanged
				;otherwise:
	pop	psw		;recall the toggle setting
	cmc			;flip the toggle
	push	psw		;save the new toggle setting
	jmp	start		;don't display the toggle command
				;just get the next input character
;
;OPTION 1: DISPLAY WITHOUT UNDERLINING
;
same	pop	psw		;recall the toggle setting
	jc	under		;if the carry flag is 1, go to
				;underlining mode of display
				;otherwise: 
	push	psw		;save the current toggle setting
				;(which is for nonunderlining)
	mov	a,b		;put the current character in A
	call	print		;display it (not underlined)
	jmp	start		;get the next character	
;
;OPTION 2: DISPLAY WITH UNDERLINING
;
under	push	psw		;save the current toggle setting
				;(which is for underlining)
	mov	a,b		;put the current character in A
	adi	80h		;add 128 decimal to it to get the
				;same character WITH underlining
	call	print		;display it (underlined)
	jmp	start		;get the next character
;
;RESTORE OLD STACK AND RETURN TO CP/M
;
alldone	lhld	oldsp	;get old stack pointer from memory
	sphl		;make it the current stack pointer
	jmp	wboot	;return to CP/M
;
;SUBROUTINES
;
rubout	push	a	;save rubout character
	mvi	a,bksp	;
	call	print	;move cursor back one space
	mvi	a,space	;
	call	print	;blank out previously displayed character
	mvi	a,bksp	;
	call	print	;move cursor back one space
	pop	a	;recall rubout character
	call	print	;display it (effect ?)
	ret
;
print	mov	e,a	;put value of current character in reg. A
	mvi	c,conio	;use function #6 as display output
	push	psw	;save program status word
			;(value in A and toggle setting)
	call	bdos	;display current character
	pop	psw	;recall value in A
	ret
;
;PROGRAM STORAGE
;
oldsp	ds	2	;memory space for old stack pointer
	ds	32	;new stack space
stktop:			;new stack starts here
	end	100h
