;**************************** 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