;*************************** AMUS Program Label ******************************
; Filename: RESET.M68                                       Date: 11/22/89
; Category: UTIL         Hash Code: 134-040-650-147      Version: 3.0(101)
; Initials: ULTR/AM      Name: DAVID PALLMANN
; Company: ULTRASOFT CORP.                         Telephone #: 5163484848
; Related Files:
; Min. Op. Sys.:                               Expertise Level: BEG
; Special:
; Description: A program to reset a "stuck" job. Reset places the job back at
; monitor level. Usage: RESET jobname{/W}   With the /W switch, RESET will
; wait for any job I/O to finish before resetting.
;*****************************************************************************
;Copyright (C) 1989 UltraSoft Corporation.  All Rights Reserved.
;
;Written by: David Pallmann
;
;This is a job reset program.  You use it reset a job that is "stuck".  This
;is usually more convenient than resetting the entire system.
;
;RESET is a public domain program.  You may freely distribute this software,
;but not for profit.  Although RESET is believed to be safe and reliable,
;UltraSoft makes no warranty of fitness and disclaims any liability for its
;for its use.  If you discover problems with RESET, we'd like to know about
;it so we can continue to enhance it.  UltraSoft Corporation. 516-348-4848.
;
;Edit History:
;3.0(100)  17-Nov-89  completely rewritten. /DFP
;3.0(101)  22-Nov-89  add /W to wait for I/O completion. /DFP

       VMAJOR  =3
       VMINOR  =0
       VSUB    =0
       VEDIT   =101.
       VWHO    =0

       SEARCH  SYS
       SEARCH  SYSSYM
       SEARCH  TRM

;constants

       LF      =12
       CR      =15

;variables

       .OFINI
       .OFDEF  JOB,    4               ; job name to reset
       .OFDEF  FLAGS,  2               ; flags:
               F$LOG   =1              ;   log off job
               F$WAIT  =2              ;   wait for I/O completion
       .OFSIZ  MEMSIZ

;macros

DEFINE  CRT     N
       MOVW    #-1_8.+^D<N>,D1
       TCRT
       ENDM

DEFINE  BITW    SRC,DST
       MOVW    DST,D7
       ANDW    SRC,D7
       ENDM

;***********
;*  START  *
;***********
;start of program
;program header and memory allocation

START:  PHDR    -1,0,PH$REE!PH$REU      ; program header
       GETIMP  MEMSIZ,A5               ; allocate memory for variables

;************
;*  CMDLIN  *
;************
;command line processing
;normal command line argument is job name
;no argument on command line displays help

CMDLIN: CALL    SWITCH                  ; process switches
       LIN                             ; end of line?
       JEQ     HELP                    ;   yes - display help
       LEA     A1,JOB(A5)              ; convert
       PACK                            ;   job name
       PACK                            ;   to RAD50
       CALL    SWITCH                  ; process switches

;************
;*  LOCATE  *
;************
;locate specified job in job table
;leave JCB address in A4
;if we can't find the job in question we have an error condition

LOCATE: MOV     JOBTBL,A0               ; point to job table
LO.CHK: MOV     (A0)+,D7                ; get a JCB address
       BEQ     LO.CHK                  ;   zero - deallocated job - skip
       CMP     D7,#-1                  ; end of job table?
       JEQ     NAMERR                  ;   yes - job specification error
       MOV     D7,A4                   ; save job control block address
       CMM     JOB(A5),JOBNAM(A4)      ; is this the job we're looking for?
       BNE     LO.CHK                  ;   no - keep on truckin'

;************
;*  SLFCHK  *
;************
;Check to see if job name specified is ourself, or our parent job, or a
;child job or ours
;It it is any of these we take no action

SLFCHK: MOV     JOBCUR,A6               ; get our own JCB
       CMP     A4,A6                   ; is this us?
       JEQ     SLFERR                  ;   yes - error
       CMP     A4,JOBATT(A6)           ; is this our parent job?
       JEQ     PARERR                  ;   yes - error
       CMP     A6,JOBATT(A4)           ; is this one of our kids?
       JEQ     KIDERR                  ;   yes - error

;************
;*  MONCHK  *
;************
;Check to see if the job really needs to be reset
;If it is at AMOS command level we will decline to take any action

MONCHK: BITW    #J.MON,JOBSTS(A4)       ; is job at AMOS command level?
       JNE     MONERR                  ;   yes - error

;************
;*  DDWAIT  *
;************
;If the DDBCHN is non-zero, wait for it to exhaust itself

DDWAIT: TST     DDBCHN                  ;
       BEQ     20$                     ;
       TYPECR  Waiting for disk queue  ;
10$:    TST     DDBCHN                  ;
       BNE     10$                     ;
20$:

;************
;*  IOWAIT  *
;************
;If the job is in the middle of an I/O wait, we must wait for it

IOWAIT: BITW    #F$WAIT,FLAGS(A5)       ; /W in effect?
       BEQ     30$                     ;   no
       BITW    #J.IOW,JOBSTS(A4)       ; in an I/O wait?
       BEQ     30$                     ;   no
       TTYI                            ;
       ASCII   "Waiting for job to complete I/O (press any key to abort wait)"
       BYTE    0                       ;
       EVEN                            ;
10$:    TCKI                            ;
       BEQ     20$                     ;
       BITW    #J.IOW,JOBSTS(A4)       ; still waiting for I/O completion?
       BNE     10$                     ;   yes
20$:    CRLF                            ;
30$:

;************
;*  EXWAIT  *
;************
;If the job is in the middle of an external wait, we must wait for it

EXWAIT: BITW    #F$WAIT,FLAGS(A5)       ; /W in effect?
       BEQ     30$                     ;   no
       BITW    #J.EXW,JOBSTS(A4)       ; in an external wait?
       BEQ     30$                     ;   no
       TTYI                            ;
       ASCII   "Waiting for job to return from external wait (press any key to abort wait)"
       BYTE    0                       ;
       EVEN                            ;
10$:    TCKI                            ;
       BEQ     20$                     ;
       BITW    #J.EXW,JOBSTS(A4)       ; still waiting for external wait?
       BNE     10$                     ;   yes
20$:    CRLF                            ;
30$:

;**********
;*  LOCK  *
;**********
;Lock out all other jobs from running

LOCK:   TST     DDBCHN                  ; check again just to be
       BNE     LOCK                    ;   paranoid
       JLOCK                           ; suspend other jobs

;************
;*  SETJOB  *
;************
;Set various fields of the Job Control Block

SETJOB: ORW     #J.CCA,JOBTYP(A4)       ; set ^C
       ANDW    #^C<J.GRD>,JOBTYP(A4)   ; turn off guard
       CLEAR   JOBCMD(A4),20.          ; clear job command
       CLRW    JOBCMZ(A4)              ; clear command file
       CLRW    JOBCMS(A4)              ; clear command file status
       CLR     JOBERR(A4)              ; clear error trap
       CLR     JOBFPE(A4)              ; clear floating point error trap
       CLR     JOBBPT(A4)              ; clear breakpoint
       CLR     JOBTRC(A4)              ; clear trace trap

;************
;*  SETTRM  *
;************
;Set various fields of the Terminal Control Block

SETTRM: PUSH    A5                      ; save A5
       SUPVR                           ; enter supervisor mode
       SVLOK                           ; disable interrupts
       MOV     JOBTRM(A4),D7           ; get address of Terminal Control Block
       BEQ     SE.RST                  ;   no terminal
       MOV     D7,A5                   ;

;wait for the AM350 semaphore

SE.SEM: TAS     T.SEM(A5)               ; grab AM350 semaphore
       BEQ     SE.SEM                  ;   keep trying till we get it

;clear fields of terminal control block

SE.CLR: CLR     T.ICC(A5)               ; clear character count
       CLR     T.ECC(A5)               ; clear echo character count
       CLR     T.BCC(A5)               ; clear break character count
       CLR     T.OBX(A5)               ; clear output buffer
       ANDW    #^C<T$OIP>,T.STS(A5)    ; clera output in progress flag

;flush queued terminal output

SE.FLU: MOV     T.OQX(A5),D7            ; index output queue
       BEQ     10$                     ;   it's empty
       MOV     D7,A1                   ; get the index
       QRET    A1                      ; release queue block
       MOV     A1,T.OQX(A5)            ; link the next block in
       BR      SE.FLU                  ;   keep on flushin'
10$:

;release AM350 semaphore, re-enable interrupts, exit supervisor mode

SE.RST: CLR     T.SEM(A5)               ; release semaphore
       LSTS    #0                      ; user mode, re-enable interrupts
       POP     A5                      ; get A5 back

;************
;*  RUNJOB  *
;************
;Reschedule the job for running

RUNJOB: MOV     JOBRNQ+10(A4),A1        ; index saved system stack pointer
       LEA     A2,CLEAN1               ; index job clean-up routine
       TST     JOBTRM(A4)              ; is the terminal attached?
       BNE     10$                     ;   yes - send it a message
       LEA     A2,CLEAN2               ;   no - just abort it
10$:    MOV     A2,76(A1)               ; set job's PC to call CLEAN? routine
       CLR     D6                      ;
       MOVW    JOBSTS(A4),D6           ; load job status word
       ANDW    #<J.NXT!J.TIW!J.TOW!J.SLP!J.IOW!J.EXW!J.SUS!J.SMW>,D6
       SVCA    36                      ; JRUN

       PUSH    A5                      ; force a ^C to the job
       MOV     JOBTRM(A4),D7           ;
       BEQ     20$                     ;
       MOV     D7,A5                   ;
       MOV     #'C-'@,D1               ;
       TRMICP                          ;
20$:    POP     A5                      ;

       JUNLOK                          ; unlock system

;**********
;*  WAIT  *
;**********
;Wait for the job to return to AMOS command level

WAIT:   MOV     #100.,D0                ; pre-set timeout
10$:    BITW    #J.MON,JOBSTS(A4)       ; did we get to AMOS yet?
       BNE     LOGOFF                  ;   yes
       SLEEP   #100.                   ; take a quick nap
       DBF     D0,10$                  ; loop Brett's way

;************
;*  FAILED  *
;************
;We failed in our reset attempt - admit this with our tail between our legs

FAILED: TTYI                            ; ding
       BYTE    7,0                     ;
       EVEN                            ;
       TYPECR  ?Unable to reset job    ;
       CRLF                            ;
       EXIT                            ;

;************
;*  LOGOFF  *
;************
;Reset was successful
;If /L was specified, log off user job

LOGOFF: BITW    #F$LOG,FLAGS(A5)        ; was /L specified?
       BEQ     DONE                    ;   no
       MOVW    #[DSK],JOBDEV(A4)       ;   yes - clear log device,
       CLRW    JOBDRV(A4)              ;         log drive, and
       CLRW    JOBUSR(A4)              ;         log PPN

;**********
;*  DONE  *
;**********
;We are done - say so

DONE:   TYPECR  Job has returned to AMOS command level.
       CRLF                            ;
       JMP     EXIT                    ;

;**********
;*  HELP  *
;**********
;Come here to explain command usage

HELP:   CRLF                            ;
       TYPESP  RESET Job Reset Utility version
       VCVT    START+2,OT$TRM          ;
       CRLF                            ;
       TYPECR  Copyright (C) 1989 UltraSoft Corporation.  All Rights Reserved.
       CRLF                            ;
       TYPECR  Usage: .RESET jobname {switches}
       CRLF                            ;
       TTYI                            ;
       ASCII   "Switches: /L - log off job after resetting it"
       BYTE    CR
       ASCII   "          /W - wait for I/O completion before resetting"
       BYTE    0                       ;
       EVEN                            ;
       CRLF                            ;
       CRLF                            ;

EXIT:   EXIT                            ;

;come here when the job name specified does not exist in the job table

NAMERR: TYPECR  ?Job specification error
       CRLF                            ;
       EXIT                            ;

;come here when the job specified seems to already be at AMOS command level

MONERR: TYPECR  ?Job is already at AMOS command level
       JMP     CONFIRM                 ;

;come here when the job specified is ourself

SLFERR: TYPECR  ?You may not reset yourself
       CRLF                            ;
       EXIT                            ;

;come here when the job specified is our parent job

PARERR: TYPECR  ?You may not reset your parent job
       CRLF                            ;
       EXIT                            ;

;come here when the job specified is a child job of ours

KIDERR: TYPECR  ?Job is a child job of yours
       CRLF                            ;
       JMP     CONFIRM                 ;

;*************
;*  CONFIRM  *
;*************
;Come here when a job was specified that the user probably doesn't want to
;reset, but may under some unusual circumstance.  Ask him to confirm the
;action.

CONFIRM:
       CRLF                            ;
       TYPESP  Do you want to reset it anyway?
       KBD     EXIT                    ;
       CRLF                            ;
       CMPB    @A2,#'Y                 ;
       JEQ     DDWAIT                  ;
       CRLF                            ;
       JMP     EXIT                    ;

;************
;*  CLEAN1  *
;************
;Clean-up routine for job with a terminal attached

CLEAN1: CRT     56                      ; unsplit screen
       CRT     8                       ; unlock keyboard
       CRT     28                      ; turn on cursor
       CRT     37                      ; turn on screen
       CRT     12                      ; high intensity
       CRT     24                      ; turn off graphics mode
       TTYI                            ; ding
       BYTE    7,0                     ;
CLEAN2: EXIT                            ;

;************
;*  SWITCH  *
;************
;Function:      Process switches
;
;Inputs:        A2 - command line index
;
;Outputs:       A2 - updated
;               FLAGS(A5) - flags bits set

SWITCH: BYP                             ;
       CMPB    @A2,#'/                 ;
       BNE     SW.RTN                  ;
       INC     A2                      ;
       MOVB    (A2)+,D1                ;
       UCS                             ;
       CMPB    D1,#'L                  ; /L?
       BEQ     SW.L                    ;   yes
       CMPB    D1,#'W                  ; /W?                           [101]
       BEQ     SW.W                    ;   yes                         [101]
SW.BAD: TTYI                            ;
       ASCII   "?Invalid switch /"     ;
       BYTE    0                       ;
       EVEN                            ;
       TTY                             ;
       TYPECR  < ignored>              ;
SW.RTN: RTN                             ;
SW.L:   ORW     #F$LOG,FLAGS(A5)        ; /L logs off job
       BR      SWITCH                  ;
SW.W:   ORW     #F$WAIT,FLAGS(A5)       ; /W waits for I/O completion   [101]
       BR      SWITCH                  ;                               [101]

       END