.mcall	.module
.module	UC, release=V01, version=06, comment=<UCL+ Bit Bucket>, audit=yes

; This is a specialized "handleroid" that is used  in  conjunction  with  the
; UCL+ program to store part of it's most recent input string.   UCL+  writes
; the string to UC:; the handler then parses-out the  "input file name"  part
; of the string (the section delineated by a leading blank  and  one  of  the
; trailing characters in the TRMTBL list).  This stored data can be retrieved
; for insertion into subsequent commands.   Note  that  UC:  is  an  optional
; component.   UCL+ does not require it's presence to operate  --  it's  just
; handy.   Note also that UC: must be memory-resident (loaded) if you want to
; use it.

; WARNING!!!
; This is NOT in any way shape or form a  general  purpose  handler.   It  is
; used by UCL+ as a memory-resident place to stash up to  41  words  of data,
; and has no real provisions for handling the unexpected.   Refer to the UCL+
; sources and documentation if you want to see how it is used.

.iif ndf tsx$p, tsx$p = 0
.if  ne  tsx$p
mmg$t	= 1
tim$it	= 1
.endc

.mcall	.drdef
.drdef	uc,370,0,0,0,0

maxbyt	= 82.	;Buffer length

	.enabl	lsb
	.drbeg	uc
	mov	uccqe,r4	;R4 => queue element
	mov	pc,r5		;R5 => buffer...
	add	#ucbufr-.,r5

	tst	(pc)+		;Make sure buffer starts out zeroed...
10$:	.word	0
	bne	20$
	clrb	(r5)
	inc	10$		;Set "init done" flag

20$:	mov	#maxbyt,r3	;R3 = length of buffer
	asl	q$wcnt(r4)	;Make byte count
	beq	ucdone		;Seek?
	bcs	40$		;Write?

; Read...

30$:
.if eq mmg$t
	movb	(r5)+,@q$buff(r4) ;Move a byte to user's buffer
	inc	q$buff(r4)	;Adjust user buffer pointer
.iff
	movb	(r5)+,-(sp)	;Move a byte, XM version...
	call	@$ptbyt
.endc
	sob	r3,30$		;Loop until done...
	br	ucdone

;Write...

40$:	mov	r5,r1		;Make R1 point at scratch buffer...
	add	#<scrach-ucbufr>,r1
	mov	r1,(pc)+
50$:	.word	0
60$:
.if eq mmg$t
	movb	@q$buff(r4),(r1)+ ;Move a byte from user's buffer
	inc	q$buff(r4)	;Adjust user buffer pointer
.iff
	call	@$gtbyt		;Get a byte, XM version...
	movb	(sp)+,(r1)+
.endc
	sob	r3,60$		;Loop until done

	mov	50$,r1		;R1 => scratch buffer
	mov	pc,r2		;R2 => terminator table...
	add	#trmtbl-.,r2

70$:	tstb	(r1)+		;Null byte?
	beq	ucdone		;Then it's a null string...
	cmpb	-1(r1),(r2)	;Space?
	bne	70$		;If not, keep looking
	cmpb	(r1),(r2)	;Is next char a space too?
	beq	70$		;Continue searching if so

80$:	mov	r2,r3		;R3 => terminator list
	movb	(r1)+,(r5)+	;Shift a character to buffer

90$:	cmpb	-1(r5),(r3)+	;Did that last char match a terminator?
	beq	100$		;If so, go quit
	tstb	(r3)		;End of terminator table?
	bne	90$		;Branch if not
	br	80$		;Otherwise, go shift next char

100$:	dec	r5		;Adjust buffer pointer
	clrb	(r5)		;Stuff trailing null
	.dsabl	lsb
; Quit...

ucint:
ucdone:
	.drfin	uc

ucbufr:	.blkb	maxbyt+2	;Text buffer
scrach:	.blkb	maxbyt+2	;Scratch buffer

trmtbl:	.ascii	" "		;Table of characters for terminating
	.ascii	"/"		; "input file name field"...
	.ascii	"="
	.ascii	","
	.byte	0
	.even

	.drend	uc

.end
