;**************************** AMUS Program Label ******************************
;* Filename: RECALL.LIT                                      Date: 27/09/91
;* Category: UTIL         Hash Code: 203-422-501-727      Version: 1.1 (103)
;* Initials: WBCL/AM      Name: Chris Davenport 
;* Company: Willow Blue Chip Limited                Telephone #: +44 935 22221
;* Related Files:
;* Min. Op. Sys.: AMOS 1.3D / AMOS 2.1          Expertise Level: BEG
;* Special:
;* Description: Displays all AMOS line editor buffers and allows selection
;* of any buffer by number.  Also allows all buffers to be cleared.
;* Similar to the VAX/VMS recall command.
;*****************************************************************************

; To avoid excessive keystrokes it is recommended that RECALL.LIT is renamed
; to something shorter (eg. R.LIT).  It is distributed as RECALL to reduce
; the chances of it clashing with other software.

; This program was written by: Chris Davenport
;                              57 Lyde Road,
;                              Yeovil,
;                              Somerset,
;                              England
;                              + 44 935 72541
;
; This is a private submission by the author and is not connected in any
; way with Willow Blue Chip Ltd except through that firms' corporate
; membership of AMUS.  Willow Blue Chip Ltd does not accept any responsibility
; whatsoever for this software.

; Permission is granted to any individual or institution to copy or use this
; software and the routines described in it, except for explicitly commercial
; purposes. This software must not be sold to any person or institution.

;;;;;;;;;;;;;;;;;;;;;;;;;;;; D I S C L A I M E R ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; No warranty of the software or of the accuracy of the documentation     ;;
;; surrounding it is expressed or implied, and author does not acknowledge ;;
;; any liability resulting from program or documentation errors.           ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Edit History
; *** Version 1.0 ***
;	[100] on 22 August 1991 by Chris Davenport.
;		Original.
;
;	[101] on 27 September 1991 by Chris Davenport.
;		Changed the help message and added label and disclaimer
;		information to prepare for its debut on the AMUS network.
;			1.0 (101)	743-745-551-743
;
; *** Version 1.1 ***
;	[102] on 4 October 1991 by Chris Davenport.
;		Why do I make life difficult for myself?  In trying to
;		keep the similarity with VMS recall, I blinded myself
;		to the much easier and more friendly way of doing things.
;		Now prompts user for buffer number instead of dropping
;		down to AMOS and requiring a further command to do the
;		actual buffer recall.
;		Update help message and changed it so that it always
;		displays the current program name regardless of what
;		the user renames it to.
;			1.1 (102)	402-217-337-666
;
;	[103} on 6 October 1991 by Chris Davenport.
;		Changed wording of prompt.  Support for backspace and
;		Control-C added.  Clear screen before displaying help.
;			1.1 (103)	203-422-501-727

; Usage:	RECALL		will display contents of recall buffers
;				and prompt user to specify one.
;		RECALL/C	will clear all recall buffers.
;		RECALL/H	will display help information.

	search	SYS
	search	SYSSYM
	search	TRM

	vmajor=	1
	vminor=	1
	vsub  = 0
	vedit =	103.
	vwho  = 0

	; Define useful ding macro.

define	DING				; Send user a bell		[102]
	mov	#7, d1			; Get a bell character		[102]
	tty				; Send it to user		[102]
endm

	; Define useful TCRT macro.

define	VDU	code
	clr	d1			; Pre-clear work register	[103]
	movw	#<-1_8.> + code, d1	; Setup TCRT code		[103]
	tcrt				; Send to user			[103]
endm

	; Define ASCII equates.

	CTRLC	= 3.			; Control-C			[103]
	BSPACE	= 177			; Backspace			[103]
	CR 	= 13.			; Carriage-return
	SPACE	= 32.			; Space				[103]

	; Define TCRT equates.

	CLRSCR	= 0			; Clear screen			[103]
	CURLFT	= 5.			; Cursor left one column	[103]

	; Layout of impure area.

	.ofini
	.ofdef	WSPACE,	2		; Workspace for LIN and NUM calls
	.ofdef	BUF,	10.		; Input line buffer
	.ofsiz	IMPSIZ

RECALL:	; *******************************************
	; ***                                     ***
	; ***   RECALL AMOS LINE EDITOR BUFFERS   ***
	; ***                                     ***
	; *******************************************

	phdr	-1, 0, PH$REE!PH$REU	; Re-entrant and re-usable

	jobidx	a0			; Index our JCB
	mov	JOBTRM(a0), a5		; Index our TCB
	mov	T.LED(a5), d7		; Index line editor stuff
	bne	10$			; - line editor active so continue
	typecr	<?No line editor for this terminal>
	exit

10$:	mov	d7, a4			; Index recall buffers
	mov	6(a4), d7
	bne	20$			; - recall buffers have been allocated
	typecr	<?No recall buffers allocated>
	exit

20$:	mov	d7, a3			; Index the top recall buffer
	byp				; Bypass white space
	lin				; End of line?
	bne	22$			; - no, parameters specified

	call	LIST			; List all line editor buffers	[102]
	call	GETNUM			; Get buffer number from user	[102]
	call	NUMBER			; Process buffer number		[102]
	call	LOCATE			; Locate buffer requested	[102]
	call	FORCE			; Force into input buffer	[102]
	exit				; Exit to AMOS			[102]

22$:	; Process switches if any.
	; Valid switches are:- /C to clear all line editor buffers.
	;		       /H for help with R.

	cmpb	@a2, #'/		; Do we have a switch?
	bne	25$			; - no
	add	#1, a2			; Skip past slash
	movb	@a2, d1			; Get switch		
	ucs				; Fold to upper case
	cmpb	d1, #'C			; Is it a /C (for CLEAR) ?
	beq	30$			; - yes
	cmpb	d1, #'H			; Is it a /H (for HELP) ?
	beq	35$			; - yes
25$:	typecr	<?Illegal switch>
	exit

30$:	call	CLRBUF			; Clear line editor buffers
	typecr	<Line editor buffers cleared>
	exit

35$:	call	HELP			; Display simple help information
	exit

LIST:	; ************************************
	; *   LIST ALL LINE EDITOR BUFFERS   *
	; ************************************

	; No parameters specified so we display a full list of the
	; current contents of all the line editor buffers.

	; Requires: A4 indexing the recall buffer area of our TCB.
	;	    A3 indexing the first recall buffer.
	; Returns : Nothing.

	clr	d2			; Pre-clear counter
	clr	d3			; Pre-clear work register
	movb	16(a4), d3		; Get number of recall buffers
10$:	call	DBUF			; Display recall buffer
	mov	@a3, a3			; Index next buffer
	dbf	d3, 10$			; and get next one
	rtn

GETNUM:	; ***********************************
	; *   GET BUFFER NUMBER FROM USER   *
	; ***********************************

	; Requires: Nothing.
	; Returns : User response in BUF(a0).

	getimp	IMPSIZ, a0		; Get some impure space		[102]

	; Put terminal into data mode and then process each character	[102]
	; entered using a little data entry routine.  In this way the	[102]
	; users' response does not get put into one of the line editor	[102]
	; buffers and so we don't have to make adjustments to cope.	[102]

	trmrst	d1			; Get terminal status word	 [102]
	orw	#T$DAT!T$ECS, d1	; Terminal to data mode w/o echo [102]
	trmwst	d1			; Put terminal status word	 [102]

	typesp	<Enter number of buffer required:>	; Prompt  [103]	[102]
	clr	d0			; Initialise count of characters[102]
	lea	a2, WSPACE(a0)		; Index character workspace	[102]

90$:	kbd	ABORT			; Get a character from user	[102]
	cmpb	d1, #CTRLC		; Control-C?			[103]
	beq	ABORT			; - yes, abort program		[103]

	cmpb	d1, #BSPACE		; Backspace?			[103]
	beq	150$			; - yes, erase last character	[103]

	movb	d1, @a2			; Put character into workspace	[102]
	lin				; Line terminator?		[102]
	beq	110$			; - yes, process user entry	[102]

	num				; Is character numeric?		[102]
	beq	100$			; - yes, continue		[102]

	DING				; - no, send user a bell	[102]
	br	90$			; Go get another character	[102]

100$:	; Character is valid.  Check that there is room in our line
	; buffer and put the character into the buffer if there is.

	cmp	d0, #9.			; Buffer full?			[102]
	blo	105$			; - no, okay to continue 	[102]
	DING				; - yes, send user a bell	[102]
	br	90$			; Go get another character	[102]

105$:	; Put character into our line buffer in the impure area.

	movb	d1, BUF(a0)[~d0]	; Put character into our buffer	[102]
	tty				; Echo back to user also	[102]
	add	#1, d0			; Increment counter		[102]
	clrb	BUF(a0)[~d0]		; Null terminate		[102]
	br	90$			; Go wait for next character	[102]

110$:	crlf				; New line			[102]
	rtn

150$:	; Process backspace.						[103]

	tst	d0			; Is there anything to rubout?	[103]
	beq	90$			; - no, go wait for next char	[103]

	sub	#1, d0			; Decrement counter		[103]
	clrb	BUF(a0)[~d0]		; Rubout character from buffer	[103]

	vdu	CURLFT			; Move cursor left one column	[103]
	mov	#SPACE, d1		; Get a space character		[103]
	tty				; Put space on top of character	[103]
	vdu	CURLFT			; Reposition cursor		[103]
	br	90$			; And go wait for next character[103]

ABORT:	DING				; Echo a bell to user		[103]
	typecr	<^C>			; Make it look real		[103]
	exit

NUMBER:	; *******************************
	; *   RECALL <number> COMMAND   *
	; *******************************
	;
	; Process RECALL <number> command.
	; Get the number of the buffer required from our special
	; input buffer in the impure area.

	; Requires: BUF(a0) containing user response.
	; Returns : D1 containing buffer number entered.
	; 	    Exits to AMOS if no number entered or if user
	;	    entered a number larger than the number of buffers.

	lea	a2, BUF(a0)		; Index character workspace	[102]
	gtdec				; Get line number required

	tst	d1			; Did user enter anything?	[102]
	bne	10$			; Non-zero so proceed		[102]
	exit				; User just pressed RETURN	[102]

10$:	clr	d3			; Pre-clear work register	[102]
	movb	16(a4), d3		; Get number of recall buffers	[102]
	addb	#1, d3			; There's actually 1 more	[102]
	cmp	d1, d3			; Is number within range?	[102]
	blos	20$			; - yes, proceed		[102]
	typecr	<?No such buffer number>;				[102]
	exit

20$:	rtn

LOCATE:	; *****************************************
	; *   FIND LINE EDITOR BUFFER REQUESTED   *
	; *****************************************

	; Now scan down the line editor buffer chain until we find the
	; buffer we are interested in.
	; Returns : A3 indexing the line editor buffer required.

	clr	d2			; Pre-clear counter
	clr	d3			; Pre-clear work register
	movb	16(a4), d3		; Get number of recall buffers
10$:	lea	a2, 10(a3)		; index start of recall buffer
	tstb	@a2			; is buffer in use?
	beq	20$			; - no, skip it

	add	#1, d2			; Increment buffer number
	cmp	d1, d2			; Is this the one?
	beq	30$			; - yes

20$:	mov	@a3, a3			; Index next buffer
	dbf	d3, 10$			; and get next one
30$:	rtn

FORCE:	; ********************************
	; *   FORCE LINE EDITOR BUFFER   *
	; ********************************
	;
	; Force line editor buffer into our input buffer.
	; Requires: A3 indexing the line editor buffer required.

	jobidx	a0			; Index our JCB
	mov	JOBTRM(a0), a5		; Index our TCB
	mov	T.IBS(a5), d4		; get size of buffer
	lea	a2, 10(a3)		; index start of recall buffer
	tstb	@a2			; is buffer in use?
	beq	20$			; - no, skip it

10$:	movb	(a2)+, d1		; get a byte
	beq	20$			; null byte terminates
	cmpb	d1, #CR			; carriage-return?
	beq	20$			; - yes, also terminates
	trmicp				; force into our input buffer
	sub	#1, d4			; decrement buffer size counter
	bne	10$			; not finished with buffer yet
20$:	rtn

DBUF:	; **********************************************
	; *   DISPLAY CONTENTS OF LINE EDITOR BUFFER   *
	; **********************************************
	;
	; Requires: A5 indexing our TCB.
	;	    A3 indexing the recall buffer to be displayed.
	;	    D2 containing recall buffer number.
	; Returns : D2 incremented if recall buffer is in use.
	; Uses    : A2, D1, D4

	mov	T.IBS(a5), d4		; get size of each buffer
	lea	a2, 10(a3)		; index start of recall buffer
	tstb	@a2			; is buffer in use?
	beq	20$			; - no, skip it

	add	#1, d2			; Increment recall buffer number
	mov	d2, d1			; Get recall buffer number
	dcvt	0, OT$TRM		; Display buffer number
	typesp	<. >

10$:	movb	(a2)+, d1		; get a byte
	beq	20$			; null byte terminates
	tty				; send it to user
	sub	#1, d4			; decrement buffer size counter
	bne	10$			; not finished this buffer yet
20$:	rtn

CLRBUF:	; ****************************************
	; *   CLEAR LINE EDITOR RECALL BUFFERS   *
	; ****************************************

	; Uses : D3, D7, A0, A6

	jobidx	a0			; Index our JCB
	mov	JOBTRM(a0), a0		; Index our TCB
	mov	T.LED(a0), d7		; Index line editor stuff
	beq	90$			; - no line editor active

	mov	d7, a0			; Index recall buffers
	mov	6(a0), d7		; Look at top recall buffer
	beq	90$			; - no recall buffers allocated

	mov	d7, a6			; Index the top recall buffer
	clr	d3			; Pre-clear work register
	movb	16(a0), d3		; get number of recall buffers
10$:	clrb	10(a6)			; clear recall buffer
	mov	@a6, a6			; index next buffer
	dbf	d3, 10$			; and get next one
90$:	rtn

HELP:	; ****************************
	; *   DISPLAY HELP MESSAGE   *
	; ****************************

	vdu	CLRSCR				; Clear screen		[103]
	call	DSPPRG				; Display program name	[102]
	type	< - Recall AMOS line editor buffers>
	tab
	tab
	typesp	<Version>
	lea	a5, RECALL			; Index this program	[102]
	vcvt	PH.VER(a5), OT$TRM		; Display version number[102]
	crlf
	crlf
	typesp	<Enter>
	call	DSPPRG				; Display program name	[102]
	typecr	< with no  switches to  get a list of the current contents>
	typecr	<of each  of the  line editor buffers.   Against  each  item will be a>
	typecr	<number.   You will then be prompted to enter the number of one of the>
	typecr	<lines listed.  If you just press RETURN you will be returned to AMOS.>
	typecr	<When you enter the number of one of the  buffers the contents of that>
	typecr	<buffer  will become  your current  command line.   You can then amend>
	typecr	<the line or press RETURN to execute it as normal.>
	crlf
	typecr	<Switches:->
	call	DSPPRG				; Display program name	[102]
	ttyi
	ascii	./.
	even
	typecr	<C will clear all line editor buffers.>
	call	DSPPRG				; Display program name	[102]
	ttyi
	ascii	./.
	even
	typecr	<H will display this help information.>
	crlf
	typecr	<This program was written by Chris Davenport who may be>
	typecr	<contacted at 57 Lyde Road, Yeovil, Somerset, England.>
	typecr	<There is no warranty on this software and the author>
	typecr	<does not acknowledge any liability resulting from its>
	typecr	<use.  It is freely donated to all Alpha Micro users.>
	typecr	<Permission is granted to use this software at no charge>
	typecr	<provided that this message is not changed or deleted from>
	typecr	<any copy of this software.>
	crlf
	rtn

DSPPRG:	; ************************************
	; *   DISPLAY CURRENT PROGRAM NAME   *
	; ************************************

	; It is quite possible that the user has followed our recommendation
	; and renamed the RECALL program to something shorter.  Since we may
	; not know what it is we pick up the program name from the JCB.

	; Requires: Nothing.
	; Returns : Nothing.

	jobidx	a5			; Index our JCB			[102]
	lea	a1, jobprg(a5)		; Index current program name	[102]
	push				; save some room for unpack	[102]
	push				; ditto				[102]
	mov	sp, a2			; index space for RAD50 convert	[102]
	unpack				; convert			[102]
	unpack				;  ditto			[102]
	mov	sp, a2			; index ASCII program name	[102]
	ttyl	@a2			; display program name		[102]
	pop				; restore stack			[102]
	pop				;   ditto			[102]
	rtn

	end