.TITLE DRDRIVER - RM03 DISK DRIVER .IDENT /01/ ; ; COPYRIGHT (C) 1977 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A ; SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH THE INCLU- ; SION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE, OR ANY ; OTHER COPIES THEREOF, MAY NOT BE PROVIDED OR OTHERWISE MADE ; AVAILABLE TO ANY OTHER PERSON EXCEPT FOR USE ON SUCH SYSTEM ; AND TO ONE WHO AGREES TO THESE LICENSE TERMS. TITLE TO AND ; OWNERSHIP OF THE SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT ; NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL ; EQUIPMENT CORPORATION. ; ; DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ; SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC. ; ; D. N. CUTLER, LEN KAWELL 23-NOV-77 ; ; RM03 DISK DRIVER ; ; MACRO LIBRARY CALLS ; $CRBDEF ;DEFINE CRB OFFSETS $EMBDEF ;DEFINE EMB OFFSETS $IODEF ;DEFINE I/O FUNCTION CODES $IRPDEF ;DEFINE IRP OFFSETS $MBADEF ;DEFINE MBA REGISTER OFFSETS $PRDEF ;DEFINE PROCESSOR REGISTERS $UCBDEF ;DEFINE UCB OFFSETS $VECDEF ;DEFINE INTERRUPT DISPATCH VECTOR OFFSETS ; ; LOCAL MACROS ; ; EXECUTE FUNCTION AND BRANCH ON RETRIABLE ERROR CONDITION ; .MACRO EXFUNC BDST,FCODE .IF NB FCODE MOVZBL #CD'FCODE,R0 .ENDC BSBW FEX .BYTE BDST-.-1 .ENDM ; ; GENERATE FUNCTION TABLE ENTRY AND CASE TABLE INDEX SYMBOL ; .MACRO GENF FCODE CD'FCODE=.-FTAB .BYTE FCODE!RM_CS1_M_GO .ENDM ; ; LOCAL SYMBOLS ; ; RM03 MASSBUS REGISTER OFFSETS ; $DEFINI RM $DEF RM_CS1 .BLKL 1 ;DRIVE CONTROL REGISTER _VIELD RM_CS1,0,<- ; DRIVE CONTROL REGISTER BIT DEFINITIONS ,- ; GO BIT - ; FUNCTION CODE > ; $DEF RM_DS .BLKL 1 ;DRIVE STATUS REGISTER _VIELD RM_DS,0,<- ; DRIVE STATUS REGISTER BIT DEFINITIONS ,- ; OFFSET MODE <,5>,- ; RESERVED BITS ,- ; VOLUME VALID ,- ; DRIVE READY ,- ; DRIVE PRESENT ,- ; PROGRAMMABLE ,- ; LAST SECTOR TRANSFERED ,- ; DRIVE WRITE LOCKED ,- ; MEDIUM ONLINE ,- ; POSITIONING IN PROGRESS ,- ; COMPOSITE ERROR - ; ATTENTION ACTIVE > ; $DEF RM_ER1 .BLKL 1 ;ERROR REGISTER 1 _VIELD RM_ER1,0,<- ; ERROR REGISTER 1 BIT DEFINITIONS ,- ; ILLEGAL FUNCTION ,- ; ILLEGAL REGISTER ,- ; REGISTER MODIFY REFUSED ,- ; PARITY ERROR ,- ; FORMAT ERROR ,- ; WRITE CLOCK FAIL ,- ; ECC HARD ERROR ,- ; HEADER COMPARE ERROR ,- ; HEADER CRC ERROR ,- ; ADDRESS OVERFLOW ERROR ,- ; ILLEGAL ADDRESS ERROR ,- ; WRITE LOCK ERROR ,- ; DRIVE TIMING ERROR ,- ; OPERATION INCOMPLETE ,- ; DRIVE UNSAFE - ; DATA CHECK ERROR > ; $DEF RM_MR .BLKL 1 ;MAINTENANCE REGISTER $DEF RM_AS .BLKL 1 ;ATTENTION SUMMARY REGISTER $DEF RM_DA .BLKL 1 ;DESIRED SECTOR/TRACK ADDRESS REGISTER _VIELD RM_DA,0,<- ; DESIRED ADDRESS FIELD DEFINITIONS ,- ; DESIRED SECTOR ADDRESS <,3>,- ; RESERVED BITS - ; DESIRED TRACK ADDRESS > ; $DEF RM_DT .BLKL 1 ;DRIVE TYPE REGISTER _VIELD RM_DT,0,<- ; DRIVE TYPE REGISTER FIELD DEFINITIONS ,- ; DRIVE TYPE NUMBER <,2>,- ; RESERVED BITS - ; DRIVE REQUEST REQUIRED > ; $DEF RM_LA .BLKL 1 ;LOOKAHEAD REGISTER $DEF RM_SN .BLKL 1 ;SERIAL NUMBER REGISTER $DEF RM_OF .BLKL 1 ;OFFSET REGISTER _VIELD RM_OF,0,<- ; OFFSET REGISTER BIT DEFINITIONS ,- ; OFFSET VALUE ,- ; DATA CHECK IN PROGRESS (SOFTWARE) ,- ; OFFSET MODE (SOFTWARE) ,- ; HEADER COMPARE INHIBIT ,- ; ECC INHIBIT - ; 16-BIT FORMAT > ; $DEF RM_DC .BLKL 1 ;DESIRED CYLINDER ADDRESS $DEF RM_UNUSED .BLKL 1 ;UNUSED $DEF RM_MR2 .BLKL 1 ;MAINTENANCE REGISTER 2 $DEF RM_ER2 .BLKL 1 ;ERROR REGISTER 2 _VIELD RM_ER2,3,<- ; ERROR REGISTER 2 BIT DEFINITIONS ,- ; DATA PARITY ERROR <,3>,- ; RESERVED BITS ,- ; DEVICE CHECK ERROR <,2>,- ; RESERVED BITS ,- ; LOSS OF BIT CLOCK ERROR ,- ; LOSS OF SYSTEM CLOCK ERROR ,- ; INVALID COMMAND ERROR ,- ; OPERATOR PLUG ERROR ,- ; SEEK INCOMPLETE ERROR - ; BAD SECTOR ERROR > ; $DEF RM_EC1 .BLKL 1 ;ECC POSITION REGISTER _VIELD RM_EC1,0,<> ; ECC POSITION FIELD $DEF RM_EC2 .BLKL 1 ;ECC PATTERN REGISTER _VIELD RM_EC2,0,<> ; ECC PATTERN FIELD $DEFEND RM ; ; DEFINE DEVICE DEPENDENT UNIT CONTROL BLOCK OFFSETS ; $DEFINI UCB .=UCB$W_BCR+2 ; $DEF UCB$L_DR_SR .BLKL 1 ;SAVED MBA STATUS REGISTER $DEF UCB$W_DR_ER2 .BLKW 1 ;SAVED RM03 ERROR REGISTER 2 .BLKW 1 ;SPARE UNUSED WORD $DEFEND UCB ; ; HARDWARE FUNCTION CODES ; F_NOP=0*2 ;NO OPERATION F_SEEK=2*2 ;SEEK CYLINDER F_RECAL=3*2 ;RECALIBRATE F_DRVCLR=4*2 ;DRIVE CLEAR F_RELEASE=5*2 ;RELEASE DRIVE F_OFFSET=6*2 ;OFFSET HEADS F_RETCENTER=7*2 ;RETURN TO CENTERLINE F_READPRESET=8*2 ;READ IN PRESET F_PACKACK=9*2 ;PACK ACKNOWLEDGE F_SEARCH=12*2 ;SEARCH FOR SECTOR F_SEARCHA=12*2 ;SEARCH AHEAD FOR SECTOR F_WRITECHECK=20*2 ;WRITE CHECK DATA F_WRITECHECKH=21*2 ;WRITE CHECK HEADER AND DATA F_WRITEDATA=24*2 ;WRITE DATA F_WRITEHEAD=25*2 ;WRITE HEADER AND DATA F_READDATA=28*2 ;READ DATA F_READHEAD=29*2 ;READ HEADER AND DATA ; ; LOCAL DATA ; ; DRIVER DISPATCH TABLE ; .PSECT WIONONPAGED DR$DDT:: ;ADDRESS OF DRIVER DISPATCH TABLE .LONG STARTIO ;START I/O OPERATION .LONG UNSOLNT ;UNSOLICITED INTERRUPT .LONG FUNCTABLE ;FUNCTION DECISION TABLE .LONG 0 ;CANCEL I/O ENTRY POINT .LONG REGDUMP ;REGISTER DUMP ROUTINE .WORD +<<3+5+1>*4> ;SIZE OF DIAGNOSTIC BUFFER .WORD +<1*4>+ ;SIZE OF ERROR BUFFER ; ; DATA CHECK FUNCTION TRANSLATION TABLE ; CHECKTAB: ; .BYTE CDF_WRITECHECK ;WRITE DATA .BYTE CDF_WRITECHECK ;READ DATA .BYTE CDF_WRITECHECKH ;WRITE HEADER AND DATA .BYTE CDF_WRITECHECKH ;READ HEADER AND DATA ; ; HARDWARE I/O FUNCTION CODE TABLE ; FTAB: ; GENF F_NOP ;NO OPERATION GENF F_NOP ;(NO UNLOAD FUNCTION) GENF F_SEEK ;SEEK CYLINDER GENF F_RECAL ;RECALIBRATE GENF F_DRVCLR ;DRIVE CLEAR GENF F_RELEASE ;RELEASE PORT GENF F_OFFSET ;OFFSET HEADS GENF F_RETCENTER ;RETURN HEADS TO CENTERLINE GENF F_PACKACK ;PACK ACKNOWLEDGE GENF F_SEARCH ;SEARCH FOR SECTOR GENF F_WRITECHECK ;WRITE CHECK GENF F_WRITEDATA ;WRITE DATA GENF F_READDATA ;READ DATA GENF F_WRITEHEAD ;WRITE HEADER AND DATA GENF F_READHEAD ;READ HEADER AND DATA GENF F_WRITECHECKH ;WRITE CHECK HEADER AND DATA GENF F_READPRESET ;READ IN PRESET GENF F_SEARCHA ;SEARCH AHEAD OF SECTOR ; ; OFFSET TABLE FOR RM03 ; OFFTAB: ; .BYTE 0 ;RETURN TO CENTERLINE .BYTE ^X01 ;+ OFFSET (BIT 0 = OFFSET FLAG) .BYTE ^X81 ;- OFFSET (BIT 0 = OFFSET FLAG) .BYTE 0 ;RETURN TO CENTERLINE OFFSIZ=.-OFFTAB ;SIZE OF OFFSET TABLE .PAGE .SBTTL RM03 FUNCTION DECISION TABLE ;+ ; RM03 FUNCTION DECISION TABLE ;- FUNCTABLE: ;FUNCTION DECISION TABLE FUNCTAB ,- ;LEGAL FUNCTIONS ;MODIFY FILE ATTRIBUTES FUNCTAB ,- ;BUFFERED I/O FUNCTIONS ;MODIFY FILE ATTRIBUTES FUNCTAB ACP$READBLK,- ;READ FUNCTIONS ;READ VIRTUAL BLOCK FUNCTAB ACP$WRITEBLK,- ;WRITE FUNCTIONS ;WRITE VIRTUAL BLOCK FUNCTAB ACP$ACCESS, ;ACCESS AND CREATE FILE OR DIRECTORY FUNCTAB ACP$DEACCESS, ;DEACCESS FILE FUNCTAB ACP$MODIFY,- ; ;MODIFY FILE ATTRIBUTES FUNCTAB EXE$ZEROPARM,- ;ZERO PARAMETER FUNCTIONS ;PACK ACKNOWLEDGE FUNCTAB EXE$ONEPARM,- ;ONE PARAMETER FUNCTIONS ;SEARCH FOR SECTOR .PAGE .SBTTL START I/O OPERATION ;+ ; STARTIO - START I/O OPERATION ON DEVICE UNIT ; ; THIS ENTRY POINT IS ENTERED TO START AN I/O OPERATION ON A DEVICE UNIT. ; ; INPUTS: ; ; R3 = ADDRESS OF I/O PACKET. ; R5 = UCB ADDRESS OF DEVICE UNIT. ; ; OUTPUTS: ; ; ******OUTPUTS******* ;- STARTIO: ;START I/O OPERATION MOVB UCB$B_ERTMAX(R5),UCB$B_ERTCNT(R5) ;INITIALIZE ERROR RETRY COUNT MOVW IRP$W_FUNC(R3),UCB$W_FUNC(R5) ;SAVE FUNCTION CODE AND MODIFIERS MOVL IRP$L_MEDIA(R3),R0 ;GET PARAMETER LONGWORD ; ; MOVE FUNCTION DEPENDENT PARAMETERS TO UCB ; 10$: EXTZV #IRP$V_FCODE,#IRP$S_FCODE,- ;EXTRACT I/O FUNCTION CODE IRP$W_FUNC(R3),R1 ; CMPB #IO$_SEEK,R1 ;SEEK FUNCTION? BEQL 20$ ;IF EQL YES CMPB #IO$_OFFSET,R1 ;OFFSET FUNCTION? BEQL 30$ ;IF EQL YES CMPB #IO$_SEARCH,R1 ;SEARCH FUNCTION? BEQL 40$ ;IF EQL YES MOVL R0,UCB$W_DA(R5) ;STORE PARAMETER LONGWORD CMPB #IO$_WRITECHECKH,R1 ;DISJOINT FUNCTION CODE? BGTRU 50$ ;IF GTRU NO SUBW #IO$_WRITECHECKH-IO$_READHEAD-1,R1 ;CONVERT TO DENSE FUNCTION CODE BRB 50$ ; ; ; SEEK FUNCTION - SET CYLINDER ADDRESS ; 20$: MOVW R0,UCB$W_DC(R5) ;SET CYLINDER ADDRESS BRB 50$ ; ; ; OFFSET FUNCTION - SET CURRENT OFFSET VALUE ; 30$: MOVB R0,UCB$W_OFFSET(R5) ;SET OFFSET VALUE BRB 50$ ; ; ; SEARCH FUNCTION - SET SECTOR ADDRESS ; 40$: MOVB R0,UCB$W_DA(R5) ;SET SECTOR ADDRESS ; ; FINISH PREPROCESSING ; 50$: MOVB R1,UCB$B_FEX(R5) ;SAVE FUNCTION DISPATCH INDEX MOVL UCB$L_CRB(R5),R4 ;GET ADDRESS OF CRB MOVL @CRB$L_INTD+VEC$L_IDB(R4),R4 ;GET FIRST CONTROLLER CSR ADDRESS BBSC #UCB$V_ECC,UCB$W_DEVSTS(R5),FDISPATCH ;CLEAR ECC CORRECTION MADE ; ; CENTRAL FUNCTION DISPATCH ; FDISPATCH: ;FUNCTION DISPATCH MOVZBL UCB$B_FEX(R5),R0 ;GET DISPATCH FUNCTION CODE BICW #UCB$M_CANCEL!- ;CLEAR CANCEL I/O, UCB$M_POWER!- ;POWERFAIL, AND UCB$M_TIMOUT,UCB$W_STS(R5) ;TIMEOUT STATUS BITS MOVB #RM_OF_M_FMT/256,UCB$W_OFFSET+1(R5) ;CLEAR ECI, HCI, AND SET FORMAT MOVB #1,UCB$B_OFFRTC(R5) ;SET INITIAL OFFSET RETRY COUNT CLRB UCB$B_OFFNDX(R5) ;CLEAR INITIAL OFFSET TABLE INDEX CASE R0,<- ;DISPATCH TO FUNCTION HANDLING ROUTINE WRITECHECK,- ;WRITE CHECK DATA WRITEDATA,- ;WRITE DATA READDATA,- ;READ DATA WRITEHEAD,- ;WRITE HEADER AND DATA READHEAD,- ;READ HEADER AND DATA WRITECHECKH,- ;WRITE CHECK HEADER AND DATA >,LIMIT=#CDF_WRITECHECK ; ; ; NO OPERATION, SEEK, RECALIBRATE, DRIVE CLEAR, RELEASE, OFFSET, ; RETURN TO CENTER LINE, PACK ACKNOWLEDGE, SEARCH, AND READ IN PRESET ; NOP: ;NO OPERATION SEEK: ;SEEK CYLINDER RECAL: ;RECALIBRATE DRVCLR: ;DRIVE CLEAR RELEASE: ;RELEASE PORT OFFSET: ;OFFSET READ HEADS RETCENTER: ;RETURN TO CENTERLINE PACKACK: ;PACK ACKNOWLEDGE SEARCH: ;SEARCH FOR SECTOR READPRESET: ;READIN PRESET EXFUNC RETRY ;EXECUTE HOUSEKEEPING FUNCTION BRB NORMAL ; ; ; WRITE CHECK DATA AND WRITE CHECK HEADER AND DATA ; WRITECHECK: ;WRITE CHECK DATA WRITECHECKH: ;WRITE CHECK HEADER AND DATA BBSC #IO$V_DATACHECK,UCB$W_FUNC(R5),WRITEDATA ;CLEAR DATA CHECK REQUEST ; ; WRITE DATA, WRITE HEADER AND DATA, WRITE CHECK DATA, AND WRITE CHECK HEADER ; AND DATA ; WRITEDATA: ;WRITE DATA WRITEHEAD: ;WRITE HEADER AND DATA BISB #RM_OF_M_ECI/256,UCB$W_OFFSET+1(R5) ;INHIBIT ECC CORRECTION ; ; READ DATA, READ HEADER AND DATA, WRITE DATA, WRITE HEADER AND DATA, WRITE ; CHECK DATA, AND WRITE CHECK HEADER AND DATA ; READDATA: ;READ DATA READHEAD: ;READ HEADER AND DATA BBS #IO$V_INHSEEK,UCB$W_FUNC(R5),TRANRQCH ;IF SET, NO EXPLICIT SEEK EXFUNC RETRY,F_SEARCHA ;SEARCH AHEAD OF STARTING SECTOR ; ; DATA TRANSFER - REQUEST CHANNEL ; TRANRQCH: ;DATA TRANSFER REQUEST CHANNEL REQPCHAN LOW ;REQUEST PRIMARY CHANNEL FOR TRANSFER ; ; DATA TRANSFER - CHANNEL ALREADY OWNED ; TRANNOCH: ;DATA TRANSFER CHANNEL OWNED MOVZBL UCB$B_FEX(R5),R0 ;GET FUNCTION DISPATCH INDEX EXFUNC TRANXT ;EXECUTE TRANSFER FUNCTION ; ; DATA CHECK ; DATACHECK: ;DATA CHECK BBC #IO$V_DATACHECK,UCB$W_FUNC(R5),NORMAL ;IF CLR, NO DATA CHECK MOVZWL #SS$_WASECC,R0 ;ASSUME ECC CORRECTION WAS MADE BBS #UCB$V_ECC,UCB$W_DEVSTS(R5),CHECKXT ;IF SET, ECC CORRECTION MADE RELCHAN ;RELEASE CHANNEL MOVB #/256,UCB$W_OFFSET+1(R5) ;SET FORMAT MOVB #1,UCB$B_OFFRTC(R5) ;SET INITIAL OFFSET RETRY COUNT CLRB UCB$B_OFFNDX(R5) ;CLEAR INITIAL OFFSET TABLE INDEX MOVL UCB$L_IRP(R5),R2 ;GET ADDRESS OF IRP MOVQ IRP$L_SVAPTE(R2),UCB$L_SVAPTE(R5) ;RESET TRANSFER PARAMETERS MOVL IRP$L_MEDIA(R2),UCB$W_DA(R5) ; ; ; DATA CHECK RETRY ; CHECKRETRY: ;DATA CHECK RETRY REQPCHAN LOW ;REQUEST PRIMARY CHANNEL FOR DATA CHECK MOVZBL UCB$B_FEX(R5),R0 ;GET FUNCTION DISPATCH INDEX MOVZBL CHECKTAB-CDF_WRITEDATA[R0],R0 ;GET CASE TABLE INDEX EXFUNC TRANXT ;EXECUTE DATA CHECK FUNCTION ; ; SUCCESSFUL OPERATION COMPLETION ; NORMAL: ; MOVZWL #SS$_NORMAL,R0 ;SET NORMAL COMPLETION STATUS CHECKXT: ; BRW FUNCXT ; ; ; TRANSFER ENDED WITH A RETRIABLE ERROR ; TRANXT: ;TRANSFER EXIT CMPB #CDF_WRITEDATA,UCB$B_CEX(R5) ;WRITE DATA FUNCTION? BEQL RETRY ;IF EQL YES CMPB #CDF_WRITEHEAD,UCB$B_CEX(R5) ;WRITE HEADER FUNCTION? BEQL RETRY ;IF EQL YES BITL #MBA$M_SR_DLT!- ;DATA LATE OR, MBA$M_SR_INVMAP!- ;INVALID MAP REGISTER OR, MBA$M_SR_MAPPE!- ;MAP REGISTER PARITY ERROR OR, MBA$M_SR_MCPE!- ;MASSBUS CONTROL PARITY ERROR OR, MBA$M_SR_MDPE!- ;MASSBUS DATA PARITY ERROR OR, MBA$M_SR_MXF!- ;MISSED TRANSFER OR, MBA$M_SR_NED!- ;NONEXISTENT DISK OR, MBA$M_SR_RDS!- ;READ DATA SUBSTITUTE OR, MBA$M_SR_WCKLWR!- ;WRITE CHECK LOWER BYTE OR, MBA$M_SR_WCKUPR,R1 ;WRITE CHECK UPPER BYTE? BNEQ RETRY ;IF NEQ YES - RETRY FUNCTION BITW #RM_ER2_M_DPE!- ;DATA PARITY ERROR OR, RM_ER2_M_DVC!- ;DEVICE CHECK OR, RM_ER2_M_LBC!- ;LOSS OF BIT CLOCK OR, RM_ER2_M_LSC!- ;LOSS OF SYSTEM CLOCK OR, RM_ER2_M_IVC,UCB$W_DR_ER2(R5) ;INVALID COMMAND? BNEQ RETRY ;IF NEQ YES - RETRY FUNCTION BITW #RM_ER1_M_OPI!- ;OPERATION INCOMPLETE OR, RM_ER1_M_PAR!- ;PARITY ERROR OR, RM_ER1_M_HCE!- ;HEADER COMPARE ERROR OR, RM_ER1_M_WCF,R2 ;WRITE CLOCK FAIL? BEQL ECC ;IF EQL NO RETRY: ; BRW RETRYERR ;RETRIABLE ERROR ; ; ECC, DRIVE TIMING, OR HEADER ERROR - APPLY ECC OR PERFORM OFFSET RECOVERY ; ECC: ;ECC CORRECTION MOVZWL UCB$W_BCR(R5),R0 ;GET NEGATIVE NUMBER OF BYTES REMAINING ADDW UCB$W_BCNT(R5),R0 ;CALCULATE NUMBER OF BYTES TRANSFERED MOVL R0,R1 ;COPY NUMBER OF BYTES TRANSFERED BEQL OFF ;IF EQL NONE - PERFORM OFFSET RECOVERY BBS #RM_ER1_V_HCRC,R2,10$ ;IF SET, HEADER CRC ERROR DECL R0 ;SET TO TRUNCATE LAST BLOCK TRANSFERED 10$: BICW #^X1FF,R0 ;TRUNCATE RESIDUAL BYTES TRANSFERED BITW #RM_ER1_M_DTE!- ;DRIVE TIMING ERROR OR, RM_ER1_M_ECH!- ;ECC HARD ERROR OR, RM_ER1_M_HCRC,R2 ;HEADER CRC ERROR? BNEQ OFF ;IF NEQ YES - PERFORM OFFSET RECOVERY BBS #RM_OF_V_ECI,UCB$W_OFFSET(R5),OFF ;IF SET, ECC INHIBITED PUSHL R1 ;SAVE TOTAL NUMBER OF BYTES TRANSFERED BSBW IOC$APPLYECC ;APPLY ECC CORRECTION POPL R0 ;RETRIEVE TRANSFERED BYTE COUNT BSBW IOC$UPDATRANSP ;UPDATE TRANSFER PARAMETERS TSTW UCB$W_BCNT(R5) ;ANY MORE TO TRANSFER? BEQL 20$ ;IF EQL NO BRW TRANNOCH ;TRANSFER NEXT SEGMENT 20$: BRW DATACHECK ;CHECK FOR WRITE CHECK ; ; OFF - OFFSET RECOVERY ; ; THIS CODE IS EXECUTED WHEN A DRIVE TIMING ERROR, HEADER COMPARE, OR ECC ; HARD ERROR IS DETECTED ON A READ FUNCTION. ; OFF: ;OFFSET RECOVERY TSTL R0 ;ANY GOOD DATA TRANSFERED? BEQL 20$ ;IF EQL NO ; ; THE TRANSFER ENDED IN AN ERROR BUT THERE WERE SECTORS TRANSFERED THAT ; CONTAINED GOOD DATA. SINCE THE ERROR COULD HAVE BEEN CAUSED BY A CYLIN- ; DER CROSSING, THE GOOD DATA IS SAVED AND THE TRANSFER IS RETRIED FROM THE ; POINT OF ERROR. ; BSBW IOC$UPDATRANSP ;UPDATE TRANSFER PARAMETERS CLRB UCB$B_OFFNDX(R5) ;RESET OFFSET TABLE INDEX 10$: MOVB #16,UCB$B_OFFRTC(R5) ;SET OFFSET RETRY COUNT RELCHAN ;RELEASE CHANNEL BICW #RM_OF_M_OM,UCB$W_OFFSET(R5) ;CLEAR OFFSET MODE CMPB #OFFSIZ,UCB$B_OFFNDX(R5) ;ALL OFFSETS TRIED? BNEQ 50$ ;IF NEQ NO BRB FATALERR ; ; ; NO GOOD DATA TRANSFERED - CHECK IF CHANGE IN OFFSET NEEDED ; 20$: BITW #RM_ER1_M_DCK!- ;DATA CHECK OR, RM_ER1_M_DTE!- ;DRIVE TIMING OR, RM_ER1_M_ECH,R2 ;ECC HARD ERROR? BNEQ 30$ ;IF NEQ YES BISB #RM_OF_M_HCI/256,UCB$W_OFFSET+1(R5) ;SET HEADER COMPARE INHIBIT 30$: DECB UCB$B_OFFRTC(R5) ;CHANGE CURRENT OFFSET? BNEQ 60$ ;IF NEQ NO INCB UCB$B_OFFNDX(R5) ;UPDATE OFFSET TABLE INDEX MOVZBL UCB$B_OFFNDX(R5),R0 ;GET NEXT OFFSET TABLE INDEX MOVB OFFTAB-1[R0],UCB$W_OFFSET(R5) ;GET NEXT OFFSET VALUE BEQL 10$ ;IF EQL RETURN TO CENTERLINE MOVB #2,UCB$B_OFFRTC(R5) ;SET OFFSET RETRY COUNT RELCHAN ;RELEASE CHANNEL BISB #RM_OF_M_OM/256,UCB$W_OFFSET+1(R5) ;SET OFFSET MODE 50$: BICB #RM_OF_M_HCI/256,UCB$W_OFFSET+1(R5) ;CLEAR HEADER COMPARE INHIBIT 60$: BBS #RM_OF_V_DCK,UCB$W_OFFSET(R5),70$ ;IF SET, DATA CHECK FUNCTION BRW TRANRQCH ;TRY FUNCTION AGAIN 70$: BRW CHECKRETRY ;TRY DATA CHECK AGAIN ; ; RETRIABLE ERROR ; RETRYERR: ;RETRIABLE ERROR BBS #RM_ER2_V_SKI,UCB$W_DR_ER2(R5),10$ ;IF SET, SEEK INCOMPLETE BBC #RM_ER1_V_HCE,R2,20$ ;IF CLR, HEADER COMPARED 10$: EXFUNC FATALERR,F_RECAL ;RECALIBRATE HEADS MOVZWL #RM_ER1_M_OPI,R2 ;SET AN ERROR FOR CALLER TO SEE 20$: DECB UCB$B_ERTCNT(R5) ;ANY RETRIES LEFT? BEQL FATALERR ;IF EQL NO RELCHAN ;RELEASE CHANNEL IF OWNED BRW FDISPATCH ; ; ; FATAL CONTROLLER/DRIVE ERROR, ERROR RETRY COUNT EXHAUSTED, ERROR RETRY ; INHIBITED, OR FINAL OFFSET TRIED ; FATALERR: ;FATAL ERROR - SET STATUS BBC #RM_DS_V_MOL,R0,10$ ;IF CLR, MEDIUM OFFLINE BBC #RM_DS_V_VV,R0,20$ ;IF CLR, VOLUME INVALID MOVZWL #SS$_UNSAFE,R0 ;SET DRIVE UNSAFE STATUS BBS #RM_ER1_V_UNS,R2,FUNCXT ;IF SET, DRIVE UNSAFE MOVZWL #SS$_OPINCOMPL,R0 ;SET OPERATION INCOMPLETE STATUS BBS #RM_ER1_V_OPI,R2,FUNCXT ;IF SET, OPERATION INCOMPLETE MOVZWL #SS$_FORMAT,R0 ;SET FORMAT ERROR STATUS BBS #RM_ER1_V_FER,R2,FUNCXT ;IF SET, FORMAT ERROR ; MOVZWL #SS$_BADBLK,R0 ;SET BAD BLOCK ERROR STATUS ; BBS #RM_ER2_V_BSE,UCB$W_DR_ER2(R5),FUNCXT ;IF SET, BAD SECTOR ERROR MOVZWL #SS$_WRITLCK,R0 ;SET WRITE LOCK ERROR STATUS BBS #RM_ER1_V_WLE,R2,FUNCXT ;IF SET, WRITE LOCK ERROR MOVZWL #SS$_IVADDR,R0 ;SET INVALID DISK ADDRESS STATUS BITW #RM_ER1_M_AOE!- ;DISK ADDRESS OVERFLOW OR, RM_ER1_M_IAE,R2 ;INVALID DISK ADDRESS ERROR? BNEQ FUNCXT ;IF NEQ YES MOVZWL #SS$_DRVERR,R0 ;SET DRIVE ERROR STATUS BITW #RM_ER1_M_DTE!- ;DRIVE TIMING ERROR OR, RM_ER1_M_ILF!- ;ILLEGAL FUNCTION OR, RM_ER1_M_ILR!- ;ILLEGAL REGISTER OR, RM_ER1_M_RMR!- ;REGISTER MODIFY REFUSE OR, RM_ER1_M_WCF,R2 ;WRITE CLOCK FAIL ERROR? BNEQ FUNCXT ;IF NEQ YES MOVZWL #SS$_PARITY,R0 ;SET PARITY ERROR STATUS BITW #RM_ER1_M_DCK!- ;DATA CHECK ERROR OR, RM_ER1_M_ECH!- ;ECC HARD ERROR OR, RM_ER1_M_HCE!- ;HEADER COMPARE ERROR OR, RM_ER1_M_HCRC!- ;HEADER CRC ERROR OR, RM_ER1_M_PAR,R2 ;PARITY ERROR? BNEQ FUNCXT ;IF NEQ YES BITL #MBA$M_SR_MAPPE!- ;MAP PARITY ERROR OR, MBA$M_SR_MCPE!- ;MASSBUS CONTROL PARITY ERROR OR, MBA$M_SR_MDPE!- ;MASSBUS DATA PARITY ERROR OR, MBA$M_SR_RDS,R1 ;READ DATA SUBSTITUTE? BNEQ FUNCXT ;IF NEQ YES MOVZWL #SS$_DATACHECK,R0 ;SET DATA CHECK ERROR STATUS BITW #MBA$M_SR_WCKLWR!- ;WRITE CHECK ERROR LOWER BYTE OR, MBA$M_SR_WCKUPR,R1 ;WRITE CHECK ERROR UPPER BYTE? BNEQ FUNCXT ;IF NEQ YES MOVZWL #SS$_NONEXDRV,R0 ;SET NONEXISTENT DRIVE STATUS BBS #MBA$V_SR_NED,R1,FUNCXT ;IF SET, NONEXISTENT DRIVE MOVZWL #SS$_CTRLERR,R0 ;SET CONTROLLER ERROR STATUS BRB FUNCXT ; 10$: MOVZWL #SS$_MEDOFL,R0 ;SET MEDIUM OFFLINE STATUS BRB FUNCXT ; 20$: MOVZWL #SS$_VOLINV,R0 ;SET VOLUME INVALID STATUS ; ; FUNCTION COMPLETION COMMON EXIT ; FUNCXT: ;FUNCTION EXIT PUSHR #^M ;SAVE REGISTERS BSBW IOC$DIAGBUFILL ;FILL DIAGNOSTIC BUFFER IF PRESENT RELCHAN ;RELEASE CHANNEL IF OWNED CMPB #CDF_WRITECHECK,UCB$B_FEX(R5) ;DRIVE RELATED FUNCTION? BGTRU 10$ ;IF GTRU YES CMPB #CDF_READPRESET,UCB$B_FEX(R5) ;READIN PRESET FUNCTION? BEQL 10$ ;IF EQL YES MOVL UCB$L_IRP(R5),R2 ;RETRIEVE ADDRESS OF IRP ADDW3 UCB$W_BCR(R5),IRP$W_BCNT(R2),2(SP) ;CALCULATE BYTES TRANSFERED 10$: POPR #^M ;RESTORE REGISTERS REQCOM ;COMPLETE REQUEST .PAGE .SBTTL RM03 HARDWARE FUNCTION EXECUTION ; ; FEX - RM03 HARDWARE FUNCTION EXECUTION ; ; THIS ROUTINE IS CALLED VIA A BSB WITH A BYTE IMMEDIATELY FOLLOWING THAT ; SPECIFIES THE ADDRESS OF AN ERROR ROUTINE. ALL DATA IS ASSUMED TO HAVE BEEN ; SET UP IN THE UCB BEFORE THE CALL. THE APPROPRIATE PARAMETERS ARE LOADED ; INTO DEVICE REGISTERS AND THE FUNCTION IS INITIATED. IF THE FUNCTION IS AN ; IMMEDIATE FUNCTION CONTROL RETURNS IMMEDIATELY. ELSE THE RETURN ADDRESS ; IS STORED IN THE UCB AND A WAITFOR INTERRUPT IS EXECUTED. WHEN THE INTER- ; RUPT OCCURS, CONTROL IS RETURNED TO THE CALLER. ; ; INPUTS: ; ; R0 = FUNCTION TABLE DISPATCH INDEX. ; R3 = ADDRESS OF DRIVE CONTROL STATUS REGISTER 1. ; R4 = ADDRESS OF MBA CONFIGURATION STATUS REGISTER. ; R5 = DEVICE UNIT UCB ADDRESS. ; ; 00(SP) = RETURN ADDRESS OF CALLER. ; 04(SP) = RETURN ADDRESS OF CALLER'S CALLER. ; ; IMMEDIATELY FOLLOWING INLINE AT THE CALL SITE IS A BYTE WHICH CONTAINS ; A BRANCH DESTINATION TO AN ERROR RETRY ROUTINE. ; ; OUTPUTS: ; ; THERE ARE FOUR EXITS FROM THIS ROUTINE: ; ; 1. SPECIAL CONDITION - THIS EXIT IS TAKEN IF A POWER FAILURE OCCURS ; OR THE OPERATION TIMES OUT. IT IS A JUMP TO THE APPROPRIATE ; ERROR ROUTINE. ; ; 2. FATAL ERROR - THIS EXIT IS TAKEN IF A FATAL CONTROLLER OR DRIVE ; ERROR OCCURS OR IF ANY ERROR OCCURS AND ERROR RETRY IS ; INHIBITED. IT IS A JUMP TO THE FATAL ERROR EXIT ROUTINE. ; ; 3. RETRIABLE ERROR - THIS EXIT IS TAKEN IF A RETRIABLE CONTROLLER ; OR DRIVE ERROR OCCURS AND ERROR RETRY IS NOT INHIBITED. ; IT CONSISTS OF TAKING THE ERROR BRANCH EXIT. ; ; 4. SUCCESSFUL OPERATION - THIS EXIT IS TAKEN IF NO ERROR OCCURS ; DURING THE OPERATION. IT CONSISTS OF A RETURN INLINE. ; ; IN ALL CASES IF AN ERROR OCCURS, AN ATTEMPT IS MADE TO LOG THE ERROR. ; ; IN ALL CASES FINAL DRIVE AND CONTROLLER REGISTERS ARE RETURNED VIA ; THE GENERAL REGISTERS R0, R1, AND R2, AND THE UCB. ; ; R0 = DRIVE STATUS REGISTER. ; R1 = MBA STATUS REGISTER. ; R2 = DRIVE ERROR REGISTER 1. ; ; UCB$W_EC1(R5) = ECC POSITION REGISTER. ; UCB$W_EC2(R5) = ECC PATTERN REGISTER. ; UCB$W_BCR(R5) = BYTE COUNT REGISTER. ; UCB$W_DR_ER2(R5) = DRIVE ERROR REGISTER 2. ; FEX: ;FUNCTION EXECUTOR POPL UCB$L_DPC(R5) ;SAVE DRIVER PC VALUE MOVB R0,UCB$B_CEX(R5) ;SAVE CASE INDEX MOVZBL UCB$B_SLAVE+1(R5),R3 ;GET DRIVE OFFSET CONSTANT MOVAL MBA$L_ERB(R4)[R3],R3 ;GET ADDRESS OF DRIVE REGISTERS CASE R0,<- ;DISPATCH TO PROPER FUNCTION ROUTINE POSIT,- ;SEEK CYLINDER EXFNC,- ;RECALIBRATE IMMED,- ;DRIVE CLEAR IMMED,- ;RELEASE DRIVE IMMED,- ;OFFSET HEADS EXFNC,- ;RETURN TO CENTERLINE IMMED,- ;PACK ACKNOWLEDGE POSIT,- ;SEARCH FOR SECTOR XFER,- ;WRITE CHECK XFER,- ;WRITE DATA XFER,- ;READ DATA XFER,- ;WRITE HEADER AND DATA XFER,- ;READ HEADER AND DATA XFER,- ;WRITE CHECK HEADER AND DATA IMMED,- ;READIN PRESET SEARCHA,- ;SEARCH AHEAD >,LIMIT=#CDF_SEEK ; ; ; IMMEDIATE FUNCTION EXECUTION ; ; FUNCTIONS INCLUDE: ; ; NO OPERATION, ; DRIVE CLEAR, ; RELEASE PORT, ; OFFSET, ; READ IN PRESET, AND ; PACK ACKNOWLEDGE. ; ; THESE FUNCTIONS ARE EXECUTED IMMEDIATELY AND THE FINAL DEVICE REGISTERS ; ARE RETURNED TO THE CALLER. ; IMMED: ;IMMEDIATE FUNCTION EXECUTION DSBINT ;DISABLE INTERRUPTS BBS #UCB$V_POWER,UCB$W_STS(R5),ENBXIT ;IF SET, POWER HAS FAILED MOVZBL #F_DRVCLR!1,RM_CS1(R3) ;CLEAR DRIVE ERRORS MOVZBL FTAB[R0],RM_CS1(R3) ;EXECUTE FUNCTION BRB ENBXIT ; ; ; SEARCH AHEAD FUNCTION EXECUTION ; ; THIS FUNCTION MINIMIZES ROTATIONAL LATENCY BY SEARCHING FOR THE SECTOR THAT IS ; FOUR SECTORS AHEAD OF THE STARTING SECTOR OF A TRANSFER. ; ; THE DESIRED CYLINDER, TRACK, AND SECTOR ADDRESS REGISTERS ARE LOADED, THE ; FUNCTION IS INITIATED, AND A WAITFOR INTERRUPT IS EXECUTED. WHEN THE INTER- ; RUPT OCCURS, THE FINAL DEVICE REGISTERS ARE RETURNED TO THE CALLER. ; SEARCHA: ; MOVZWL UCB$W_DA(R5),R1 ;GET DESIRED TRACK AND SECTOR ADDRESS SUBB #4,R1 ;COMPUTE FOUR SECTORS BEFORE IT BGEQ 10$ ;IF GEQ BEFORE SECTOR ZERO ADDB UCB$B_SECTORS(R5),R1 ;CONVERT TO AFTER SECTOR ZERO 10$: MOVL R1,RM_DA(R3) ;SET TRACK AND SECTOR ADDRESS BRB LDCYL ; ; ; TRANSFER FUNCTION EXECUTION ; ; FUNCTIONS INCLUDE: ; ; WRITE CHECK, ; WRITE CHECK HEADER AND DATA, ; WRITE DATA, ; WRITE HEADER AND DATA, ; READ DATA, AND ; READ HEADER AND DATA. ; ; THE MAP REGISTERS, BYTE COUNT REGISTER, AND VIRTUAL ADDRESS REGISTER ARE ; LOADED FOLLOWED BY THE DESIRED CYLINDER, TRACK, AND SECTOR ADDRESS REGISTERS. ; THE FUNCTION IS INITIATED AND A WAITFOR INTERRUPT IS EXECUTED. WHEN THE ; INTERRUPT OCCURS, THE FINAL DEVICE REGISTERS ARE RETURNED TO THE CALLER. ; ; IT ASSUMED THAT THE CALLER OWNS THE CHANNEL ON WHICH THE I/O IS TO OCCUR. ; XFER: ;TRANSFER FUNCTION EXECUTION MCOML #0,MBA$L_SR(R4) ;CLEAR MASSBUS ADAPTER ERRORS LOADMBA ;LOAD MAP, BYTE COUNT, AND VIRTUAL ADDRESS MOVZBL UCB$B_CEX(R5),R0 ;RETRIEVE FUNCTION TABLE INDEX ; ; POSITIONING FUNCTION EXECUTION ; ; FUNCTIONS INCLUDE: ; ; SEEK CYLINDER, AND ; SEARCH FOR SECTOR. ; ; THE DESIRED CYLINDER, TRACK, AND SECTOR ADDRESS REGISTERS ARE LOADED, THE ; FUNCTION IS INITIATED, AND A WAITFOR INTERRUPT IS EXECUTED. WHEN THE INTER- ; RUPT OCCURS, THE FINAL DEVICE REGISTERS ARE RETURNED TO THE CALLER. ; POSIT: ;POSITION FUNCTION EXECUTION MOVZWL UCB$W_DA(R5),RM_DA(R3) ;SET DESIRED TRACK AND SECTOR ADDRESS LDCYL: ; MOVZWL UCB$W_DC(R5),RM_DC(R3) ;SET DESIRED CYLINDER ADDRESS ; ; INTERRUPT WAIT FUNCTION EXECUTION ; ; FUNCTIONS INCLUDE: ; ; RECALIBRATE, AND ; RETURN TO CENTERLINE. ; ; THE OFFSET REGISTER IS LOADED, THE FUNCTION IS INITIATED, AND A WAITFOR ; INTERRUPT IS EXECUTED. WHEN THE INTERRUPT OCCURS, THE FINAL DEVICE REGISTERS ; ARE RETURNED TO THE CALLER. ; EXFNC: ;EXECUTE FUNCTION MOVZBL #F_DRVCLR!1,RM_CS1(R3) ;CLEAR DRIVE ERRORS BBC #RM_OF_V_OM,UCB$W_OFFSET(R5),10$ ;IF CLR, NO OFFSET ACTIVE MOVZBL #F_OFFSET!1,RM_CS1(R3) ;SET DRIVE IN OFFSET MODE 10$: DSBINT ;DISABLE INTERRUPTS BBS #UCB$V_POWER,UCB$W_STS(R5),ENBXIT ;IF SET, POWER FAILED MOVZWL UCB$W_OFFSET(R5),RM_OF(R3) ;SET FORMAT, INHIBIT BITS, AND OFFSET MOVZBL FTAB[R0],RM_CS1(R3) ;INITIATE FUNCTION WFIKPCH RETREG,#6 ;WAITFOR INTERRUPT AND KEEP CHANNEL MOVL MBA$L_SR(R4),UCB$L_DR_SR(R5) ;SAVE FINAL CONTROLLER STATUS IOFORK ;CREATE FORK PROCESS BRB RETREG ; ; ; ENABLE INTERRUPTS ; ENBXIT: ; ENBINT ;ENABLE INTERRUPTS ; ; RETURN REGISTERS ; RETREG: ;RETURN FINAL DEVICE REGISTERS CVTLW RM_ER2(R3),UCB$W_DR_ER2(R5) ;SAVE ERROR REGISTER 2 CVTLW RM_EC1(R3),UCB$W_EC1(R5) ;SAVE ECC POSITION REGISTER CVTLW RM_EC2(R3),UCB$W_EC2(R5) ;SAVE ECC PATTERN REGISTER CVTLW MBA$L_BCR(R4),UCB$W_BCR(R5) ;SAVE BYTE COUNT REGISTER MOVL RM_DS(R3),R0 ;GET CONTENTS OF DRIVE STATUS REGISTER MOVL UCB$L_DR_SR(R5),R1 ;RETRIEVE FINAL CONTROLLER STATUS MOVL RM_ER1(R3),R2 ;GET CONTENTS OF DRIVE ERROR REGISTER 1 BITW #UCB$M_POWER!- ;POWER FAIL OR DEVICE TIMEOUT? UCB$M_TIMOUT,UCB$W_STS(R5) ; BNEQ 40$ ;IF NEQ YES - SPECIAL CONDITION CMPB #CDF_WRITECHECK,UCB$B_CEX(R5) ;DRIVE RELATED FUNCTION? BGTRU 10$ ;IF GTRU YES CMPB #CDF_READPRESET,UCB$B_CEX(R5) ;READIN PRESET FUNCTION? BEQL 10$ ;IF EQL YES ; ; CONTROLLER RELATED FUNCTION ; BITL #MBA$M_ERROR,R1 ;ANY CONTROLLER ERRORS? BEQL 30$ ;IF EQL NO BSBW ERL$DEVICERR ;ALLOCATE AND FILL ERROR MESSAGE BUFFER BBS #IO$V_INHRETRY,UCB$W_FUNC(R5),50$ ;IF SET, RETRY INHIBITED BITL #MBA$M_SR_ERCONF!- ;ERROR CONFIRMATION OR, MBA$M_SR_ISTO!- ;INTERFACE SEQUENCE TIMEOUT OR, MBA$M_SR_PGE!- ;PROGRAMMING ERROR OR, MBA$M_SR_RDTO,R1 ;READ TIMEOUT? BNEQ 50$ ;IF NEQ YES - FATAL CONTROLLER ERROR BITL #MBA$M_SR_DLT!- ;DATA LATE OR, MBA$M_SR_INVMAP!- ;INVALID MAP REGISTER OR, MBA$M_SR_MAPPE!- ;MAP REGISTER PARITY ERROR OR, MBA$M_SR_MBEXC!- ;MASSBUS EXCEPTION OR, MBA$M_SR_MCPE!- ;MASSBUS CONTROL PARITY ERROR OR, MBA$M_SR_MDPE!- ;MASSBUS DATA PARITY ERROR OR, MBA$M_SR_MXF!- ;MISSED TRANSFER OR, MBA$M_SR_NED!- ;NONEXISTENT DRIVE OR, MBA$M_SR_RDS!- ;READ DATA SUBSTITUTE OR, MBA$M_SR_WCKLWR!- ;WRITE CHECK LOWER BYTE OR, MBA$M_SR_WCKUPR,R1 ;WRITE CHECK UPPER BYTE? BNEQ 20$ ;IF NEQ YES - RETRIABLE CONTROLLER ERROR ; ; DRIVE RELATED FUNCTION ; 10$: BBC #RM_DS_V_ERR,R0,30$ ;IF CLR, NO DRIVE ERRORS BSBW ERL$DEVICERR ;ALLOCATE AND FILL ERROR MESSAGE BUFFER BBS #IO$V_INHRETRY,UCB$W_FUNC(R5),50$ ;IF SET, RETRY INHIBITED 20$: BBC #RM_DS_V_MOL,R0,50$ ;IF CLR, MEDIUM OFFLINE BBC #RM_DS_V_VV,R0,50$ ;IF CLR, INVALID VOLUME BITW #RM_ER1_M_AOE!- ;ADDRESS OVERFLOW OR, RM_ER1_M_FER!- ;FORMAT ERROR OR, RM_ER1_M_IAE!- ;INVALID ADDRESS OR, RM_ER1_M_ILF!- ;ILLEGAL FUNCTION OR, RM_ER1_M_ILR!- ;ILLEGAL REGISTER OR, RM_ER1_M_RMR!- ;REGISTER MODIFY REFUSE OR, RM_ER1_M_UNS!- ;DRIVE UNSAFE OR, RM_ER1_M_WLE,R2 ;WRITE LOCK ERROR? BNEQ 50$ ;IF NEQ YES - FATAL DRIVE ERROR BITW #RM_ER2_M_BSE!- ;BAD SECTOR ERROR OR, RM_ER2_M_OPE,UCB$W_DR_ER2(R5) ;OPERATOR PLUG ERROR? BNEQ 50$ ;IF NEQ YES - FATAL DRIVE ERROR ; ; RETRIABLE ERROR EXIT ; CVTBL @UCB$L_DPC(R5),-(SP) ;GET BRANCH DISPLACEMENT ADDL (SP)+,UCB$L_DPC(R5) ;CALCULATE RETURN ADDRESS - 1 30$: INCL UCB$L_DPC(R5) ;ADJUST TO CORRECT RETURN ADDRESS JMP @UCB$L_DPC(R5) ;RETURN TO DRIVER ; ; SPECIAL CONDITION EXIT ; 40$: CMPB #CDF_WRITECHECK,UCB$B_CEX(R5) ;DRIVE RELATED FUNCTION? BGTRU 45$ ;IF GTRU YES CMPB #CDF_READPRESET,UCB$B_CEX(R5) ;DRIVE RELATED FUNCTION? BLEQU 45$ ;IF LEQU YES MOVL #MBA$M_CR_ABORT,MBA$L_CR(R4) ;ABORT CURRENT TRANSFER 45$: SETIPL UCB$B_FIPL(R5) ;LOWER IPL TO DRIVE FOK LEVEL MOVL #MBA$M_CR_IE,MBA$L_CR(R4) ;ENABLE MBA INTERRUPTS ; ; FATAL CONTROLLER OR DRIVE ERROR EXIT ; 50$: BRW FATALERR ; .PAGE .SBTTL RM03 REGISTER DUMP ROUTINE ; ; REGDUMP - RM03 REGISTER DUMP ROUTINE ; ; THIS ROUTINE IS CALLED TO SAVE THE CONTROLLER AND DRIVE REGISTERS IN A ; SPECIFIED BUFFER. IT IS CALLED FROM THE DEVICE ERROR LOGGING ROUTINE AND ; FROM THE DIAGNOSTIC BUFFER FILL ROUTINE. ; ; INPUTS: ; ; R0 = ADDRESS OF REGISTER SAVE BUFFER. ; R4 = ADDRESS OF ADAPTER CONFIGURATION REGISTER. ; R5 = DEVICE UNIT UCB ADDRESS. ; ; OUTPUTS: ; ; THE CONTROLLER AND DRIVE REGISTERS ARE SAVED IN THE SPECIFIED BUFFER. ; REGDUMP: ;RM03 REGISTER DUMP ROUTINE MOVL #/4,(R0)+ ;INSERT NUMBER OF DEVICE REGISTERS MOVL MBA$L_CSR(R4),(R0)+ ;SAVE CONFIGURATION REGISTER MOVL MBA$L_CR(R4),(R0)+ ;SAVE CONTROL REGISTER MOVL UCB$L_DR_SR(R5),(R0)+ ;SAVE STATUS REGISTER MOVL MBA$L_VAR(R4),(R0)+ ;SAVE VIRTUAL ADDRESS REGISTER MOVL MBA$L_BCR(R4),(R0)+ ;SAVE BYTE COUNT REGISTER EXTZV #9,#8,-8(R0),R1 ;GET FINAL MAP REGISTER NUMBER MOVL MBA$L_MAP(R4)[R1],(R0)+ ;SAVE FINAL MAP REGISTER CONTENTS CLRL (R0)+ ;ASSUME NO PREVIOUS MAP REGISTER DECL R1 ;CALCULATE PREVIOUS MAP REGISTER NUMBER BLSS 10$ ;IF LSS NONE MOVL MBA$L_MAP(R4)[R1],-4(R0) ;SAVE PREVIOUS MAP REGISTER CONTENTS 10$: MOVZBL #/4,R1 ;SET NUMBER OF DRIVE REGISTERS TO SAVE MOVZBL UCB$B_SLAVE+1(R5),R2 ;GET DRIVE OFFSET CONSTANT MOVAL MBA$L_ERB(R4)[R2],R2 ;GET ADDRESS OF DRIVE REGISTERS 20$: MOVL (R2)+,(R0)+ ;SAVE DRIVE REGISTER SOBGTR R1,20$ ;ANY MORE TO SAVE? RSB ; UNSOLNT: RSB ;******TEMP******* .END