.TITLE ERROR MESSAGE PROCESSING .IDENT /V1.01/ .NLIST TOC,SYM .ENABL LC ; Part of Sira Paper Tape Punch Despooler. ; ; COPYRIGHT(C) 1981,1982 Sira Institute Ltd., ; South Hill, Chislehurst, Kent, BR7 5EH, England. ; ; Author: C.J. Doran ; ; Assemble as: ; >MAC PPPERROR=LB:[200,200]RSXMC/PA:1,[1,1]RUNMAC/ML,EXEMC/ML,SY:[g,m]PPPERROR ;+ ; Error message output. All messages are sent to the console by a breakthrough ; write. Error message routines return to caller. ;- ; MODIFICATIONS RECORD ; ==================== ; V1.01 14-Jul-82 CJD ; Allow for case where TI: is not yet known (TIUCB=0), and don't ; try to report error there. ; Switch to system state while following redirect chains. .MCALL QIOW$M,ALUN$R,DIR$,UCBDF$,DCBDF$ UCBDF$ DCBDF$ .PSECT CODE,I,RO ; QIOERR -- Error code is in QIO DPB I/O status block. ; ; Message takes the form: ; ; PP0 -*DIAG* QIO error NNN ; QIOERR::MOVB IOSTAT,%1 ; Fetch error code JSR %5,DECERR ; Call standard processor .WORD QIONO,QIOMSG ; Parameters ; FCSERR -- Error code is in FDB+F.ERR and FDB+F.ERR+1 . If the latter is ; negative, the code is a directive error code -- report it as such. ; ; Otherwise, message is: ; ; PP0 -*FATAL*-File error NNN ; FCSERR::MOVB FDB+F.ERR,%1 ; Fetch error byte TSTB FDB+F.ERR+1 ; Is it really an FCS error? BMI DSWERR ; No, a DSW code if FDB+F.ERR+1 is -ve JSR %5,DECERR ; Yes, call standard processor .WORD FCSNO,FCSMSG ; ILLFRM -- Illegal form number. Message is: ; ; PP0 -*DIAG*-Illegal form No NNN ; ILLFRM::JSR %5,DECERR ; (Form number already in %1) .WORD FRMNO,FRMMSG ; DIRERR -- Directive failed. Message is: ; ; PP0 -*DIAG*-Directive error NNN ; DIRERR::MOV $DSW,%1 ; Error code is in $DSW DSWERR: JSR %5,DECERR ; Entry from FCSERR .WORD DSWNO,DSWMSG ; General-purpose error processor. Called as ; ; JSR %5,DECERR ; .WORD , ; ; where is the address in the string where the number is to ; be placed. ; and is the address of the start of the error message. ; %1 contains the error number to be placed at ; ; DECERR returns abnormally to the caller's caller, restoring %5. DECERR: MOV (%5)+,%0 ; Get address for error number CLR %2 ; Zero-suppress JSR PC,$CBDSG ; Convert to decimal ASCII MOVB #'.,(%0)+ ; Terminate with a '.' SUB @%5,%0 ; Compute length of string QIOW$M ERQIOW,,,,,,,<@%5,%0> ; Set up message MOV (SP)+,%5 ; Restore %5, purging return address BR PRTMSG ; Print and return to caller's caller ; ILLCMD -- Message from QMG is illegal in context. Message is: ; ; PP0: -*FATAL*-Command N invalid at state S ; ILLCMD::MOVB PACKET,ILLNO1 ; Get command no BISB #'0,ILLNO1 ; Assume it's a single digit MOVB STATE,ILLNO2 ; Get current state BISB #'0,ILLNO2 ; Assume that's single digit too BPL 10$ ; Digit if +ve MOVB #'-,ILLNO2 ; Change to '-' if state -1 10$: QIOW$M ERQIOW,,,,,,,<#ILLMSG,#ILLLEN> ; Set up message ; Print error message on console and, if a job is in progress, on ; the submitting terminal, if that isn't the console anyway. PRTMSG: ALUN$R AERLUN,,#"CO,#0 ; Assign LUN for CO: DIR$ #ERQIOW ; Print message on console TSTB STATE ; Job active? BLE 10$ ; Not if STATE<=0 MOV #.CO0,%0 ; Yes, get console UCB JSR PC,REDIR ; Follow redirects MOV %0,-(SP) ; To final UCB MOV TIUCB,%0 ; Repeat for TI: UCB BEQ 10$ ; Unless not known JSR PC,REDIR CMP %0,(SP)+ ; Same UCB's? BEQ 10$ ; Yes, TI:=CO:, don't repeat prompt ; Find unit number. Referring to Sections 4.1.4.1 and 4.1.2.1 of "Guide ; to Writing an I/O Driver": ; Now %0 = UCB address, ; @%0 = DCB address, ; D.UNIT(@%0) = lowest unit number on controller (byte) ; D.UCB(@%0) = lowest UCB address on controller ; D.UCBL(%0) = length of UCB ; So unit number = D.UNIT(@%0) + [%0 - D.UCB(@%0)]/D.UCBL(@%0) MOV %1,-(SP) ; Save %1 MOV %0,%1 ; Copy UCB address MOV @%0,%0 ; Get DCB address MOVB D.UNIT(%0),AERLUN+A.LUNU ; Get 1st unit number on controller MOV D.UCBL(%0),-(SP) ; Save UCB size SUB D.UCB(%0),%1 ; Compute UCB-1st UCB SXT %0 ; in double-precision (should be +ve, but be sure) DIV (SP)+,%0 ; Compute number of UCB in this DCB ADD %0,AERLUN+A.LUNU ; Add to 1st unit number MOV (SP)+,%1 ; Finished with %1 ALUN$R AERLUN,,#"TT ; Change CO0: to TTn: DIR$ #ERQIOW ; Send message to TTn: 10$: RTS PC ; Return ; Subroutine to follow a redirect chain, leading up the the final device ; UCB, when the U.RED word addresses the UCB itself. ; Enter with original UCB in %0, and update it to the final value. REDIR: CALL $SWSTK,10$ ; Don't allow redirect chain to change 5$: MOV U.RED(%0),%0 ;; Back here to follow redirect chain CMP U.RED(%0),%0 ;; End of redirect chain? BNE 5$ ;; No, follow chain MOV %0,IOSTAT ;; Yes, end of chain, put %0 where it can be retrieved RETURN ; Return to user state 10$: MOV IOSTAT,%0 ; Get final pointer from where we put it RTS PC ; back to caller .END