.TITLE XYDRIVER - XYLOGICS-CDC DISK DRIVER .IDENT /V0001/ .LIST MEB ; COPYRIGHT (C) 1978 ; MIT BATES LINEAR ACCELERATOR, MIDDLETON, MA ; ; T. J. PROVOST 10-10-78 ; T. J. PROVOST 12-21-78 ; ; XYLOGICS-CDC DISK DRIVER ; ; MACRO LIBRARY CALLS ; ; $DCDEF ;DEFINE DEVICE CLASSES AND TYPES $ADPDEF ;DEFINE ADAPTER CONTROL BLOCK OFFSETS $CRBDEF ;DEFINE CHANNEL REQUEST BLOCK OFFSETS $DDBDEF ;DEFINE DEVICE DATA BLOCK OFFSETS $DPTDEF ;DEFINE DEVICE PROLOGUE TABLE OFFSETS $EMBDEF ;DEFINE EMB OFFSETS $IDBDEF ;DEFINE INTERRUPT DISPATCH BLOCK OFFSETS $IODEF ;DEFINE I/O FUNCTION CODES $IRPDEF ;DEFINE I/O REQUEST PACKET OFFSETS $UBADEF ;DEFINE UNIBUS ADAPTER REGISTER OFFSETS $UCBDEF ;DEFINE UNIT CONTROL BLOCK OFFSETS $VECDEF ;DEFINE INTERRUPT DISPATCH VECTOR OFFSETS .PAGE .SBTTL LOCAL MACROS ; ; LOCAL MACROS ; ; EXECUTE FUNCTION AND BRANCH ON RETRIABLE ERROR CONDITION ; .MACRO EXFUNCH BDST,FCODE .IF NB FCODE MOVZBL #CD'FCODE,R3 .ENDC BSBW FEXH .BYTE BDST-.-1 .ENDM .MACRO EXFUNCL BDST,FCODE .IF NB FCODE MOVZBL #CD'FCODE,R3 .ENDC BSBW FEXL .BYTE BDST-.-1 .ENDM ; ; GENERATE FUNCTION TABLE ENTRY AND CASE TABLE INDEX SYMBOL ; .MACRO GENF FCODE CD'FCODE=.-FTAB/2 .WORD FCODE!XY_CSR_M_GO!XY_CSR_M_IE .ENDM .PAGE .SBTTL LOCAL SYMBOLS ; ; LOCAL SYMBOLS ; ; XYLOGICS-CDC CONTROLLER REGISTER OFFSETS ; $DEFINI XY $DEF XY_CSR .BLKW 1 ; CONTROL & STATUS REGISTER _VIELD XY_CSR,0,<- ; FIELD DEFINITIONS ,- ; GO BIT ,- ; FUNCTION CODE <,1>,- ; RESERVED BIT ,- ; INTERRUPT ENABLE ,- ; CONTROLLER READY ,- ; OFFSET ,- ; MEMORY EXTENSION BITS ,- ; SEEK INHIBIT ,- ; CONTROLLER ERROR > ; $DEF XY_DA .BLKW 1 ; DISK ADDRESS REGISTER (USH) _VIELD XY_DA,0,<- ; FIELD DEFINITIONS ,- ; DESIRED SECTOR ADDRESS ,- ; DESIRED TRACK (HEAD) ADDRESS ,- ; DRIVE SELECT (UNIT) <,2>,- ; RESERVED BITS > $DEF XY_BA .BLKW 1 ; BUFFER ADDRESS REGISTER $DEF XY_WC .BLKW 1 ; WORD COUNT REGISTER $DEF XY_DC .BLKW 1 ; DESIRED CYLINDER REGISTER $DEF XY_DS .BLKW 1 ; DRIVE STATUS REGISTER _VIELD XY_DS,0,<- ; FIELD DEFINITIONS ,- ; SEEK DONE INT. DISK DR ID ,- ; SEEK DONE PER DRIVE STATUS <,1>,- ; BIT RESERVED FOR MULTIPORT ,- ; SEEK DONE FLAG ,- ; DRIVE SEEKING STATUS ,- ; DRIVE STATUS (PACK?) CHANGE ,- ; DRIVE WRITE LOCKED <,1>,- ; BIT RESERVED FOR MULTIPORT ,- ; DISK DRIVE READY > $DEF XY_ER .BLKW 1 ; ERROR REGISTER _VIELD XY_ER,0,<- ; BIT DEFINITIONS ,- ; CYLINDER ADDRESS COMPARE ERROR ,- ; SECTOR/HEAD ADDRESS COMP ERR ,- ; WRITE LOCK ERROR ,- ; CYLINDER OVERFLOW ERROR ,- ; INVALID HEAD ADDR ERR (NXH) ,- ; INVALID CYLINDER ADDR ERR (NXC) ,- ; INVALID SECTOR ADDR ERR (NXS) ,- ; DATA LATE ERROR ,- ; HEADER (OR DATA) VRC (CRC) ERR ,- ; CONTROLLER TIMEOUT ERROR ,- ; SEEK INCOMPLETE (HARD SEEK) ERR ,- ; DRIVE UNSAVE (FAULT) ERROR ,- ; DRIVE TIMING (NONRDY) ERR ,- ; BAD SECTOR ERROR ,- ; WRITE CHECK ERROR ,- ; BUS TIMEOUT ERROR > ; $DEFEND XY ; ; SOFTWARE STATUS IN UPPER BYTE OF OFFSET WORD ; _VIELD XY,0,<- ;SOFTWARE STATUS BIT DEFINTIONS ,- ; ECC INHIBIT - ; DATACHECK IN PROGRESS > ; ; ; DEFINE DEVICE DEPENDENT UNIT CONTROL BLOCK OFFSETS ; $DEFINI UCB .=UCB$W_BCR+2 ; $DEF UCB$W_XY_CSR .BLKW 1 ;CONTROL STATUS REGISTER $DEF UCB$W_XY_DA .BLKW 1 ;DISK ADDRESS REGISTER $DEF UCB$W_XY_BA .BLKW 1 ;BUFFER ADDRESS REGISTER $DEF UCB$W_XY_WC .BLKW 1 ;WORD COUNT REGISTER $DEF UCB$W_XY_DC .BLKW 1 ;DESIRED CYLINDER REGISTER $DEF UCB$W_XY_DS .BLKW 1 ;DRIVE STATUS REGISTER $DEF UCB$W_XY_ER .BLKW 1 ;ERROR REGISTER $DEF UCB$W_XY_DPN .BLKW 1 ;DATAPATH NUMBER $DEF UCB$L_XY_DPR .BLKL 1 ;DATAPATH REGISTER $DEF UCB$L_XY_FMPR .BLKL 1 ;FINAL MAP REGISTER $DEF UCB$L_XY_PMPR .BLKL 1 ;PREVIOUS MAP REGISTER .BLKW 1 ;SPARE USED WORD $DEF UCB$W_CYL0 .BLKW 1 ;STARTING CYLINDER # FOR VIRTUAL DRIVE $DEF UCB$W_REALUNIT .BLKW 1 ;REAL UNIT # FOR THIS VIRTUAL UNIT $DEFEND UCB ; ; HARDWARE FUNCTION CODES ; ; THE FOLLOWING FUNCTION CODES EXIST FOR RK611 ; BUT HAVE NO EQUIVALENT ON THE XYLOGICS-CDC ; F_UNLOAD ;SELECTS DRIVE ; F_OFFSET ;DOES SEEK TO CYL ; F_RETCENTER ;DOES SEEK TO CYL ; F_PACKACK ; F_STARTSPNDL ; THE FOLLOWING FUNCTION CODES EXIST FOR XYLOGICS-CDC ; BUT HAVE NO EQUIVALENT ON THE RK611 ; F_SCLR >>> REWIND ; F_RIHC >>> READTRACKD ; F_WBWD >>> WRITECHECKH ; F_WRITEHDC >>> WRITETRACKD ; F_RNS UNUSED OPTION ; F_PRC CALCOMP DISKS ONLY ; THE FOLLOWING I/O FUNCTION CODES EXECUTE DIFFERENTLY ; ON THE RK611 AND ON THE XYLOGICS-CDC ; IO$_NOP ;RK611 SELECTS DRIVE, XYLOC TRUE NOP ; IO$_OFFSET ;RK611 SEEKS, XYLOG ONLY SETS UCB F_NOP =^XF*2 ; NO OPERATION (SELECT DRIVE) F_SEEK =^X1*2 ; SEEK CYLINDER (ONLY) F_RECAL =^XA*2 ; RECALIBRATE (RTZ) F_DRVCLR =^X9*2 ; DRIVE (FAULT) CLEAR F_RELEASE =^XC*2 ; (PORT) RELEASE DRIVE F_SCLR =^X0*2 ; SYSTEM CLEAR F_RIHC =^X7*2 ; READ DATA IGNORING HEADER CHECK F_WBWD =^X8*2 ; WRITE OVER WRITE PROTECTED SECTOR F_RNS =^XD*2 ; READ NO STRIP (OPTION) F_PRC =^XE*2 ; PORT RELEASE (CALCOMP ONLY) F_WRITECHECK =^XB*2 ; WRITE CHECK (DISK) DATA F_WRITEDATA =^X3*2 ; WRITE DATA (NORMAL) F_WRITEHEAD =^X4*2 ; (FORMAT) F_WRITEHDC =^X6*2 ; WRITE HEADER AND DATA (& CRC) F_READDATA =^X2*2 ; READ DATA (NORMAL) F_READHEAD =^X5*2 ; READ HEADER AND DATA (& CRC) .PAGE .SBTTL DRIVER PROLOGUE TABLE ; ; LOCAL DATA ; ; DRIVER PROLOGUE TABLE ; DT$_CDC=DT$_RM03 ;MIGHT AS WELL! DT$_CDCN=DT$_RM03 ;MIGHT AS WELL ; MUST CONSIDER POSSIBLE NEED FOR UNLOAD IN DPTAB ; ALSO, POSSIBLE IDB INITIALIZATION ; ALSO UCBSIZE DECREASE DPTAB - ;DEFINE DRIVER PROLOGUE TABLE END=XY_END,- ;END OF DRIVER ADAPTER=UBA,- ;ADAPTER TYPE FLAGS=DPT$M_SVP,- ;SYSTEM PAGE TABLE ENTRY REQUIRED UCBSIZE=200,- ;UCB SIZE NAME=DPDRIVER ;DRIVER NAME DPT_STORE INIT ;CONTROL BLOCK INIT VALUES DPT_STORE DDB,DDB$L_ACPD,L,<^A\F11\> ;DEFAULT ACP NAME DPT_STORE DDB,DDB$L_ACPD+3,B,3 ;ACP CLASS DPT_STORE UCB,UCB$B_FIPL,B,8 ;FORK IPL DPT_STORE UCB,UCB$L_DEVCHAR,L,- ;DEVICE CHARACTERISTICS ; RANDOM ACCESS DPT_STORE UCB,UCB$B_DEVCLASS,B,DC$_DISK ;DEVICE CLASS DPT_STORE UCB,UCB$W_DEVBUFSIZ,W,512 ;DEFAULT BUFFER SIZE DPT_STORE UCB,UCB$B_SECTORS,B,32 ;NUMBER OF SECTORS PER TRACK DPT_STORE UCB,UCB$B_TRACKS,B,19 ;NUMBER OF TRACKS PER CYLINDER DPT_STORE UCB,UCB$W_CYLINDERS,W,109 ;NUMBER OF CYLINDERS DPT_STORE UCB,UCB$L_MAXBLOCK,L,<109*19*32> ;MAXIMUM BLOCK NO. DPT_STORE UCB,UCB$B_DEVTYPE,B,DT$_CDC DPT_STORE UCB,UCB$B_DIPL,B,22 ;DEVICE IPL DPT_STORE UCB,UCB$B_ERTCNT,B,8 ;ERROR RETRY COUNT DPT_STORE UCB,UCB$B_ERTMAX,B,8 ;MAX ERROR RETRY COUNT DPT_STORE REINIT ;CONTROL BLOCK RE-INIT VALUES DPT_STORE CRB,CRB$L_INTD+4,D,XY$INT ;INTERRUPT SERVICE ROUTINE ADDRESS DPT_STORE CRB,CRB$L_INTD+VEC$L_INITIAL,D,XY_XYLOG_INIT ;CONTROLLER INIT DPT_STORE CRB,CRB$L_INTD+VEC$L_UNITINIT,D,XY_CDC_INIT ;UNIT INIT DPT_STORE DDB,DDB$L_DDT,D,DP$DDT ;DDT ADDRESS DPT_STORE END ; .PAGE .SBTTL DRIVER DISPATCH TABLE ; ; DRIVER DISPATCH TABLE ; DDTAB DP,- ;DRIVER DISPATCH TABLE XY_STARTIO,- ;START I/O OPERATION XY_UNSOLNT,- ;UNSOLICITED INTERRUPT XY_FUNCTABLE,- ;FUNCTION DECISION TABLE 0,- ;CANCEL I/O ENTRY POINT XY_REGDUMP,- ;REGISTER DUMP ROUTINE <12*4>,- ;SIZE OF DIAGNOSTIC BUFFER <12*4+> ;SIZE OF ERROR BUFFER ; ; HARDWARE I/O FUNCTION CODE TABLE ; FTAB: ; GENF F_NOP ; NO OPERATION (SELECT DRIVE) GENF F_SCLR ; SYSTEM CLEAR GENF F_SEEK ; SEEK CYLINDER (ONLY) GENF F_RECAL ; RECALIBRATE (RTZ) GENF F_DRVCLR ; DRIVE (FAULT) CLEAR GENF F_RELEASE ; (PORT) RELEASE DRIVE GENF F_RNS ; READ NO STRIP (OPTION) GENF F_PRC ; PORT RELEASE (CALCOMP ONLY) GENF F_WBWD ; WRITE OVER WRITE PROTECTED SECTOR GENF F_WRITECHECK ; WRITE CHECK (DISK) DATA GENF F_WRITEDATA ; WRITE DATA (NORMAL) GENF F_WRITEHEAD ; (FORMAT) GENF F_READDATA ; READ DATA (NORMAL) GENF F_READHEAD ; READ HEADER AND DATA (& CRC) GENF F_WRITEHDC ; WRITE HEADER AND DATA (& CRC) GENF F_RIHC ; READ DATA IGNORING HEADER CHECK ; ; OFFSET TABLE FOR XYLOGICS-CDC ; OFFTAB: ; .BYTE 0 ;RETURN TO CENTERLINE .BYTE ^X01 ;NORMAL MINUS .BYTE ^X02 ;NORMAL PLUS .BYTE ^X04 ;LATE NORMAL .BYTE ^X08 ;EARLY NORMAL .BYTE ^X05 ;LATE MINUS .BYTE ^X06 ;LATE PLUS .BYTE ^X09 ;EARLY MINUS .BYTE ^X0A ;EARLY PLUS .BYTE 0 ;RETURN TO CENTERLINE OFFSIZ=.-OFFTAB ;SIZE OF OFFSET TABLE .PAGE .SBTTL XYLOGICS-CDC FUNCTION DECISION TABLE ;+ ; XYLOGICS-CDC FUNCTION DECISION TABLE ;- ; DEFINE CDC SPECIFIC FUNCTION CODES IO$_WRITEHDC =IO$_WRITETRACKD IO$_WBWD =IO$_WRITECHECKH IO$_RIHC =IO$_READTRACKD IO$_SCLR =IO$_REWIND ;THE FOLLOWING FUNCTION CODES ARE NEVER QUEUED TO STARTIO ; THEY ARE HANDLED BY FDT ROUTINES ; ALTHOUGH THEY MAY RESULT IN FUTURE QIO'S ; SENSECHAR, SENSEMODE, SETCHAR, SETMODE ; READLBLK, READVBLK, WRITEVBLK, WRITELBLK ; ACCESS, DEACCESS, ACPCONTROL ; CREATE, DELETE, MODIFY, MOUNT ; NOP NOTIMP FDT NORMAL ; UNLOAD NOTIMP FDT NORMAL ; SEEK EXE$ONEPARM SIO IO$_SEEK ; RECAL EXE$ZEROPARM SIO IO$_RECAL ; DRVCLR EXE$ZEROPARM SIO IO$_DRVCLR ; RELEASE NOTIMP FDT NORMAL ; OFFSET XY_SETOFF FDT NORMAL ; RETCENTER XY_SETOFF FDT NORMAL ; PACKACK NOTIMP FDT NORMAL ; STARTSPNDL NOTIMP FDT NORMAL ; SENSECHAR EXE$SENSEMODE FDT ; SETCHAR EXE$SETCHAR FDT ; SENSEMODE EXE$SENSEMODE FDT ; SETMODE EXE$SETCHAR FDT ; WRITECHECK ACP$WRITEBLK SIO IO$_WRITECHECK ; WRITEHEAD ACP$WRITEBLK SIO IO$_WRITEHEAD ; READHEAD ACP$READBLK SIO IO$_READHEAD ; READLBLK ACP$READBLK ACP ; WRITELBLK ACP$WRITEBLK ACP ; READPBLK ACP$READBLK SIO IO$_READPBLK ; WRITEPBLK ACP$WRITEBLK SIO IO$_WRITEPBLK ; READVBLK ACP$READBLK ACP ; WRITEVBLK ACP$WRITEBLK ACP ; ACCESS ACP$ACCESS ACP ; ACPCONTROL ACP$MODIFY ACP ; CREATE ACP$ACCESS ACP ; DEACCESS ACP$DEACCESS ACP ; DELETE ACP$MODIFY ACP ; MODIFY ACP$MODIFY ACP ; MOUNT ACP$MOUNT ACP ; WRITEHDC ACP$WRITEBLK SIO IO$_WRITEHDC ; WBWD ACP$WRITEBLK SIO IO$_WBWD? ; RIHC ACP$READBLK SIO IO$_RIHC ; SCLR EXE$ZEROPARM SIO IO$_SCLR XY_FUNCTABLE: ;FUNCTION DECISION TABLE FUNCTAB ,- ;LEGAL FUNCTIONS ;SYSTEM CLEAR FUNCTAB ,- ;BUFFERED I/O FUNCTIONS ;MOUNT VOLUME FUNCTAB XY_SETOFF,- ;OFFSET, RETCENTER ;RETCENTER FUNCTAB XY_NOTIMP,- ;NOT IMPLEMENTED FUNCTIONS ;LOAD VOLUME FUNCTAB XY_ALIGN,- ;TEST ALIGNMENT FUNCTIONS ;WRITE OVER PROTECTED SEC FUNCTAB +ACP$READBLK,- ;READ FUNCTIONS ;READ IGNORING HEADER CHK FUNCTAB +ACP$WRITEBLK,- ;WRITE FUNCTIONS ;WRITE OVER PROTECTED SEC FUNCTAB +ACP$ACCESS, ;ACCESS AND CREATE FILE OR DIRECTORY FUNCTAB +ACP$DEACCESS, ;DEACCESS FILE FUNCTAB +ACP$MODIFY,- ; ;MODIFY FILE ATTRIBUTES FUNCTAB +ACP$MOUNT, ;MOUNT VOLUME FUNCTAB +EXE$ZEROPARM,- ;ZERO PARAMETER FUNCTIONS ;SYSTEM CLEAR FUNCTAB +EXE$ONEPARM,- ;ONE PARAMETER FUNCTIONS ;SEEK CYLINDER FUNCTAB +EXE$SENSEMODE,- ; ;SENSE MODE FUNCTAB +EXE$SETCHAR,- ; ;SET MODE .PAGE .SBTTL TEST ALIGNMENT OF BUFFER ;+ ; XY_ALIGN - TEST ALIGNMENT OF BUFFER ; ; THIS ROUTINE IS CALLED FROM THE FUNCTION DECISION TABLE DISPATCHER TO CHECK THE ; ALIGNMENT OF THE BUFFER. ; ; INPUTS: ; ; R0 = SCRATCH. ; R1 = SCRATCH. ; R2 = SCRATCH. ; R3 = ADDRESS OF I/O REQUEST PACKET. ; R4 = CURRENT PROCESS PCB ADDRESS. ; R5 = ASSIGNED DEVICE UCB ADDRESS. ; R6 = ADDRESS OF CCB. ; R7 = I/O FUNCTION CODE. ; R8 = FUNCTION DECISION TABLE DISPATCH ADDRESS. ; R9 = SCRATCH. ; R10 = SCRATCH. ; R11 = SCRATCH. ; AP = ADDRESS OF FIRST FUNCTION DEPENDENT PARAMETER. ; ; OUTPUTS: ; ; THE BUFFER BYTE COUNT IS CHECKED FOR BEING EQUAL TO 0 MOD 2. IF THE CHECK ; FAILS, THEN THE I/O OPERATION IS TERMINATED WITH AN ERROR. ELSE A RETURN ; TO THE FUNCTION DECISION TABLE DISPATCHER IS EXECUTED. ;- XY_ALIGN: ; BBS #0,4(AP),10$ ;IF SET, ODD BYTE COUNT TSTL 4(AP) ;ZERO LENGTH TRANSFER? BEQL 20$ ; EQL => YES RSB ; 10$: MOVZWL #SS$_BUFBYTALI,R0 ;SET BUFFER ALIGNMENT STATUS JMP G^EXE$ABORTIO ; 20$: MOVW #SS$_NORMAL,R0 ;NO BYTES => SUCCESSFUL XFER JMP G^EXE$FINISHIOC ; SO GO HOME HAPPY .PAGE .SBTTL NOT IMPLEMENTED FUNCTIONS ;+ ; XY_NOTIMP - DISPOSE OF FUNCTIONS WHICH DO NOT EXECUTE ANYWAY ; ; THIS ROUTINE IS CALLED FROM THE FUNCTION DECISION TABLE DISPATCHER ; TO DISPOSE OF FUNCTIONS NOT IMPLEMENTED ON THE XYLOGICS CONTROLLER ; ; INPUTS: ; ; R0 = SCRATCH. ; R1 = SCRATCH. ; R2 = SCRATCH. ; R3 = ADDRESS OF I/O REQUEST PACKET. ; R4 = CURRENT PROCESS PCB ADDRESS. ; R5 = ASSIGNED DEVICE UCB ADDRESS. ; R6 = ADDRESS OF CCB. ; R7 = I/O FUNCTION CODE. ; R8 = FUNCTION DECISION TABLE DISPATCH ADDRESS. ; R9 = SCRATCH. ; R10 = SCRATCH. ; R11 = SCRATCH. ; AP = ADDRESS OF FIRST FUNCTION DEPENDENT PARAMETER. ; ; OUTPUTS: ; ; SETS SS$_NORMAL IN R0 AND JMPS TO EXE$FINISHIOC XY_NOTIMP: ;DISPOSE OF NON-IMP CMDS MOVW #SS$_NORMAL,R0 ;SET CONDITION NORMAL (SUCCESS) JMP G^EXE$FINISHIOC ; AND GO HOME .PAGE .SBTTL OFFSET-RETCENTER HANDLED AT FDT LEVEL ;+ ; XY_SETOFF - OFFSET, RETCENTER WILL MERELY SET UCB VALUE ; ; THIS ROUTINE IS CALLED FROM THE FUNCTION DECISION TABLE DISPATCHER ; TO INSERT NEW OFFSET INTO UCB ; ; INPUTS: ; ; R0 = SCRATCH. ; R1 = SCRATCH. ; R2 = SCRATCH. ; R3 = ADDRESS OF I/O REQUEST PACKET. ; R4 = CURRENT PROCESS PCB ADDRESS. ; R5 = ASSIGNED DEVICE UCB ADDRESS. ; R6 = ADDRESS OF CCB. ; R7 = I/O FUNCTION CODE. ; R8 = FUNCTION DECISION TABLE DISPATCH ADDRESS. ; R9 = SCRATCH. ; R10 = SCRATCH. ; R11 = SCRATCH. ; AP = ADDRESS OF FIRST FUNCTION DEPENDENT PARAMETER. ; ; OUTPUTS: ; ; INSERTS OFFSET IN UCB ; SETS SS$_NORMAL IN R0 AND JMPS TO EXE$FINISHIOC XY_SETOFF: ;SET OFFSETS CLRW UCB$W_OFFSET(R5) ;ASSUME RETCENTER CMPB #IO$_RETCENTER,R7 ; IS IT? BEQL 10$ ; EQL > YES MOVW IRP$L_MEDIA(R3),UCB$W_OFFSET(R5) ;INSERT OFFSET 10$: MOVW #SS$_NORMAL,R0 ;SET CONDITION NORMAL (SUCCESS) JMP G^EXE$FINISHIOC ; AND GO HOME .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: ; ; FUNCTION DEPENDENT PARAMETERS ARE STORED IN THE DEVICE UCB, THE ERROR ; RETRY COUNT IS RESET, AND THE FUNCTION IS EXECUTED. AT FUNCTION COMPLETION ; THE OPERATION IS TERMINATED THROUGH REQUEST COMPLETE. ;- XY_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 ; ; 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 MOVL IRP$L_MEDIA(R3),- UCB$W_DA(R5) ;STORE PARAMETER LONGWORD BRB 50$ ; ; ; SEEK FUNCTION - SET CYLINDER ADDRESS ; 20$: MOVW IRP$L_MEDIA(R3),- UCB$W_DC(R5) ;SET CYLINDER ADDRESS ; ; FINISH PREPROCESSING ; 50$: MOVB R1,UCB$B_FEX(R5) ;SAVE FUNCTION CODE BICW #UCB$M_ECC!- ;CLEAR ECC CORRECTION MADE AND, UCB$M_DIAGBUF,UCB$W_DEVSTS(R5) ;DIAGNOSTIC BUFFER PRESENT BBC #IRP$V_DIAGBUF,IRP$W_STS(R3),FDISPATCH ;IF CLR, NO BUFFER BISW #UCB$M_DIAGBUF,UCB$W_DEVSTS(R5) ;SET DIAGNOSTIC BUFFER PRESENT .PAGE .SBTTL CENTRAL FUNCTION DISPATCH ; ; CENTRAL FUNCTION DISPATCH ; ;******BEWARE**** YOU CAN GET HERE FROM ELSEWHERE******* FDISPATCH: ;FUNCTION DISPATCH MOVL UCB$L_IRP(R5),R3 ;RETRIEVE ADDRESS OF I/O PACKET BBS #IRP$V_PHYSIO,IRP$W_STS(R3),10$ ;IF SET, PHYSICAL I/O FUNCTION BBS #UCB$V_VALID,UCB$W_STS(R5),10$ ;IF SET, VOLUME SOFTWARE VALID MOVZWL #SS$_VOLINV,R0 ;SET VOLUME INVALID STATUS BRW RESETXFR ; ; ; UNIT IS SOFTWARE VALID OR FUNCTION IS PHYSICAL I/O ; 10$: CLRB UCB$W_OFFSET+1(R5) ;CLEAR ECC INHIBIT AND DATACHECK IN PROGRESS CLRL UCB$W_XY_CSR(R5) ;CLEAR SEEK INHIBIT, ETC. MOVB #1,UCB$B_OFFRTC(R5) ;SET INITIAL OFFSET RETRY COUNT CLRB UCB$B_OFFNDX(R5) ;CLEAR INITIAL OFFSET TABLE INDEX ;**** DM DISPATCHES VIA CASE ;**** THIS COUNTS ON IO$_XXXX RETAINING RELATIVE VALUE ;**** ACCROSS VMS RELEASES. I DON'T BELIEVE IT, SO I ;**** DISPATCH ELSEWISE MOVZBL UCB$B_FEX(R5),R3 ;RETRIEVE FUNCTION CODE CMPB #IO$_SEEK,R3 ;IF SEEK BNEQ 20$ ;NEQ => NOT SEEK EXFUNCH RETRY,F_SEEK ;GO SEEK BRW NORMAL ;SUCCESS 20$: CMPB #IO$_RECAL,R3 ;OR RECAL BNEQ 30$ ;NEQ => NOT RECAL EXFUNCH RETRY,F_RECAL ;GO RECAL BRW NORMAL ;SUCCESS 30$: CMPB #IO$_DRVCLR,R3 ;OR DRVCLR BNEQ 40$ ;NEQ => NOT DRIVE CLEAR EXFUNCH RETRY,F_DRVCLR ;GO CLEAR DRIVE BRW NORMAL ;SUCCESS 40$: CMPB #IO$_SCLR,R3 ;OR SCLR BNEQ 50$ ;NEQ => NOT SYSTEM CLEAR EXFUNCH RETRY,F_SCLR ;GO CLEAR SYSTEM BRW NORMAL ;SUCCESS 50$: MOVB #CDF_WRITEDATA,R3 ;STUFF CASE INDEX CMPB #IO$_WRITEPBLK,UCB$B_FEX(R5) ;WRITEPBLK BEQL WRITEDATA ; =WRITEDATA MOVB #CDF_READDATA,R3 ;STUFF CASE INDEX CMPB #IO$_READPBLK,UCB$B_FEX(R5) ;READPBLK BEQL READDATA ; =READDATA MOVB #CDF_WRITECHECK ,R3 ;STUFF CASE INDEX CMPB #IO$_WRITECHECK,UCB$B_FEX(R5) ;WRITECHECK BEQL CLRDATCHK ; => CLEAR DATA CHECK MOVB #CDF_WRITEHEAD,R3 ;STUFF CASE INDEX CMPB #IO$_WRITEHEAD,UCB$B_FEX(R5) ;WRITEHEAD BEQL CLRDATCHK ; => CLEAR DATA CHECK MOVB #CDF_READHEAD,R3 ;STUFF CASE INDEX CMPB #IO$_READHEAD,UCB$B_FEX(R5) ;READHEAD BEQL CLRDATCHK ; => CLEAR DATA CHECK MOVB #CDF_WRITEHDC,R3 ;STUFF CASE INDEX CMPB #IO$_WRITEHDC,UCB$B_FEX(R5) ;WRITEHDC BEQL CLRDATCHK ; => CLEAR DATA CHECK MOVB #CDF_RIHC,R3 ;STUFF CASE INDEX CMPB #IO$_RIHC,UCB$B_FEX(R5) ;RIHC BEQL CLRDATCHK ; => CLEAR DATA CHECK MOVB #CDF_WBWD,R3 ;STUFF CASE INDEX CMPB #IO$_WBWD,UCB$B_FEX(R5) ;WBWD BEQL CLRDATCHK ; => CLEAR DATA CHECK ; ELSE IGNORE DATA CHK ; ; WRITE CHECK DATA, WRITE HEADERS, AND READ HEAD ; READ IGNORING HEADER AND CRC ; WRITE HEADER, DATA, CRC ; WRITE OVER PROTECTED SECTOR ; CLRDATCHK: BICW #IO$M_DATACHECK,UCB$W_FUNC(R5) ;CLEAR DATA CHECK REQUEST ; ; WRITE DATA, WRITE CHECK DATA, WRITE HEADERS, AND READ HEADER ; WRITEDATA: ;WRITE DATA ; ; READ DATA, WRITE DATA, WRITE CHECK DATA, WRITE HEADERS, AND READ HEADER ; READDATA: ;READ DATA BBC #IO$V_INHSEEK,- UCB$W_FUNC(R5),- TRANSFR ;IF CLEAR, EXPLICIT SEEK BISW #XY_CSR_M_SKI,- UCB$W_XY_CSR(R5) ;SET SEEK INHIBIT ; ; DATA TRANSFER ; TRANSFR: ;DATA TRANSFER REQUEST CHANNEL EXFUNCL 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_FUNC(R5),CHECKXT ;IF SET, ECC CORRECTION MADE MOVB #XY_M_DCK!- ;SET DATA CHECK IN PROGRESS XY_M_ECI,UCB$W_OFFSET+1(R5) ;AND INHIBIT ECC CORRECTION 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 EXFUNCL TRANXT,F_WRITECHECK ;EXECUTE WRITECHECK FUNCTION ; ; SUCCESSFUL OPERATION COMPLETION ; NORMAL: ; MOVZWL S^#SS$_NORMAL,R0 ;SET NORMAL COMPLETION STATUS CHECKXT: ; BRW FUNCXT ; ; ; TRANSFER ENDED WITH A RETRIABLE ERROR ; TRANXT: ;TRANSFER EXIT CMPB #CDF_WRITEHEAD,UCB$B_CEX(R5) ;WRITE HEADER FUNCTION? BEQL RETRY ;IF EQL YES CMPB #CDF_WRITEHDC,UCB$B_CEX(R5) ;WRITE HEADER, DATA, CRC FUNCTION? BEQL RETRY ;IF EQL YES CMPB #CDF_WBWD,UCB$B_CEX(R5) ;WRITE BLOCK IGNORING PROTECTION BEQL RETRY ;IF EQL YES BITW #XY_ER_M_DTE!- ;DISK TIMING ERROR, XY_ER_M_WCE!- ;WRITE CHECK ERROR? XY_ER_M_BTE!- ;BUS TIMEOUT? XY_ER_M_UNS!- ;DRIVE UNSAFE? XY_ER_M_SKI,R3 ;SEEK INCOMPLETE? 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 TSTL R2 ;HAS ER,DS BEEN CLEARED? BEQL RETRY ;YES, BETTER RETRY FROM SCRATCH 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 #XY_ER_V_HVRC,R3,10$ ;IF SET, HEADER VRC ERROR DECL R0 ;SET TO TRUNCATE LAST BLOCK TRANSFERED 10$: BICW #^X1FF,R0 ;TRUNCATE RESIDUAL BYTES XFERRED SUBL2 #^X200,R0 ;CORRECT FOR SECTOR BUFFER ; FALL THROUGH TO OFFSET RECOVERY, SINCE NO ECC EXISTS ; ; OFF - OFFSET RECOVERY ; ; THIS CODE IS EXECUTED WHEN A DRIVE TIMING ERROR, HEADER VRC, OR ECC HARD ; ERROR IS DETECTED ON A READ FUNCTION. ; OFF: ;OFFSET RECOVERY TSTL R0 ;ANY GOOD DATA TRANSFERED? BLEQ 10$ ;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. ; JSB G^IOC$UPDATRANSP ;UPDATE TRANSFER PARAMETERS CLRB UCB$B_OFFNDX(R5) ;RESET OFFSET TABLE INDEX ; BRB 20$ ; BRB 40$ ;********CUT OFFSET DEBUG******* ; ; NO GOOD DATA TRANSFERED - CHECK IF CHANGE IN OFFSET NEEDED ; 10$: BRB 40$ ;********CUT OFFSET DEBUG******* CMPB #CDF_WRITEDATA,UCB$B_CEX(R5) ;WRITE DATA FUNCTION? BEQL 40$ ;IF EQL YES DECB UCB$B_OFFRTC(R5) ;CHANGE CURRENT OFFSET? BNEQ 40$ ;IF NEQ NO MOVB #2,UCB$B_OFFRTC(R5) ;SET OFFSET RETRY COUNT 20$: INCB UCB$B_OFFNDX(R5) ;UPDATE OFFSET TABLE INDEX MOVZBL UCB$B_OFFNDX(R5),R0 ;GET NEXT OFFSET TABLE INDEX CMPB #OFFSIZ,R0 ;ALL OFFSETS TRIED? BEQL OFFSETERR ;IF EQL YES MOVB OFFTAB-1[R0],UCB$W_OFFSET(R5) ;SET NEXT OFFSET VALUE BNEQ 30$ ;IF NEQ NOT OFFSET ZERO MOVB #16,UCB$B_OFFRTC(R5) ;SET OFFSET RETRY COUNT 30$: 40$: DECB UCB$B_ERTCNT(R5) ;ANY RETRIES LEFT? BEQL FATALERR ;IF EQL NO BBS #XY_V_DCK,UCB$W_OFFSET+1(R5),50$ ;IF SET, DATA CHECK FUNCTION MOVZBL UCB$B_CEX(R5),R3 ;RETRIEVE CASE DISPATCH INDEX BRW TRANSFR ;TRY FUNCTION AGAIN 50$: BRW CHECKRETRY ;TRY DATA CHECK AGAIN ; ; RETRIABLE ERROR ; RETRYERR: ;RETRIABLE ERROR DECB UCB$B_ERTCNT(R5) ;ANY RETRIES LEFT? BEQL FATALERR ;IF EQL NO 10$: BRW FDISPATCH ; ; ; ALL OFFSETS TRIED - RETRIEVE FINAL TRANSFER STATUS ; OFFSETERR: ;OFFSET RECOVERY ERROR MOVZWL UCB$W_XY_CSR(R5),R1 ;RETRIEVE CONTROL STATUS REGISTER ; ; FATAL CONTROLLER/DRIVE ERROR, ERROR RETRY COUNT EXHAUSTED, ERROR RETRY ; INHIBITED, OR FINAL OFFSET TRIED ; FATALERR: ;FATAL ERROR - SET STATUS MOVZWL #SS$_UNSAFE,R0 ;SET DRIVE UNSAFE STATUS BBS #XY_ER_V_UNS,R3,FUNCXT ;IF SET, DRIVE UNSAFE MOVZWL #SS$_WRITLCK,R0 ;SET WRITE LOCK ERROR BBS #XY_ER_V_WLE,R3,FUNCXT ;IF SET, WRITE LOCK ERROR MOVZWL #SS$_IVADDR,R0 ;SET INVALID DISK ADDRESS STATUS BITW #XY_ER_M_COE!- ;CYLINDER ADDRESS OVERFLOW OR, XY_ER_M_IHAE!- ;INVALID HEADER ADDR ERROR? XY_ER_M_ICAE!- ;INVALID CYLINDER ADDR ERROR? XY_ER_M_ISAE,R3 ;INVALID SECTOR ADDR ERROR? BNEQ FUNCXT ;IF NEQ YES MOVZWL #SS$_DRVERR,R0 ;SET DRIVE ERROR STATUS BITW #XY_ER_M_DTE!- ;DRIVE TIMING ERROR OR, XY_ER_M_SKI,R3 ;SEEK INCOMPLETE? BNEQ FUNCXT ;IF NEQ YES MOVZWL #SS$_PARITY,R0 ;SET PARITY ERROR STATUS BITW #XY_ER_M_BSE!- ;BAD SECTOR ERROR OR, XY_ER_M_HVRC,R3 ;HEADER VRC ERROR? BNEQ FUNCXT ;IF NEQ YES MOVZWL #SS$_DATACHECK,R0 ;SET DATA CHECK ERROR STATUS BITW #XY_ER_V_WCE,R3 ;IF SET, WRITE CHECK ERROR BNEQ FUNCXT ;IF NEQ, YES MOVZWL #SS$_CTRLERR,R0 ;SET CONTROLLER ERROR STATUS ; ; FUNCTION COMPLETION COMMON EXIT ; FUNCXT: ;FUNCTION EXIT PUSHL R0 ;SAVE FINAL REQUEST STATUS JSB G^IOC$DIAGBUFILL ;FILL DIAGNOSTIC BUFFER IF PRESENT CMPB #CDF_WBWD,UCB$B_CEX(R5) ;DRIVE RELATED FUNCTION? BGTRU 10$ ;IF GTRU YES MOVL UCB$L_IRP(R5),R3 ;RETRIEVE ADDRESS OF IRP ADDW3 UCB$W_BCR(R5),IRP$W_BCNT(R3),2(SP) ;CALCULATE BYTES TRANSFERED 10$: MOVL UCB$W_XY_DS(R5),R1 ;DS,ER INTO SECOND IOSB LONGWORD POPL R0 ;RETRIEVE FINAL REQUEST STATUS REQCOM ;COMPLETE REQUEST .PAGE .SBTTL XYLOGICS-CDC HARDWARE FUNCTION EXECUTION ; ; FEXH - XYLOGICS-CDC HARDWARE FUNCTION EXECUTION (HIGH PRIORITY) ; FEXL - XYLOGICS-CDC HARDWARE FUNCTION EXECUTION (LOW PRIORITY) ; ; 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. 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: ; ; R3 = FUNCTION TABLE DISPATCH INDEX. ; R4 = ADDRESS OF CONTROL STATUS REGISTER 1. ; 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 R1, R2, AND R3, AND THE UCB. ; ; R1 = CONTROL STATUS REGISTER. ; R2 = DISK STATUS REGISTER. ; R3 = ERROR REGISTER. ; ; UCB$W_BCR(R5) = BYTE COUNT REGISTER. ; .ENABL LSB FEXH: ;FUNCTION EXECUTOR (HIGH PRIORITY) MOVAB G^IOC$REQPCHANH,R2 ;SET ADDRESS OF REQUEST CHANNEL ROUTINE BRB 10$ ; FEXL: ;FUNCTION EXECUTOR (LOW PRIORITY) MOVAB G^IOC$REQPCHANL,R2 ;SET ADDRESS OF REQUEST CHANNEL ROUTINE 10$: POPL UCB$L_DPC(R5) ;SAVE DRIVER PC VALUE MOVB R3,UCB$B_CEX(R5) ;STORE CASE INDEX JSB (R2) ;REQUEST CHANNEL CLRL R2 INSV UCB$W_REALUNIT(R5),- ;INSERT UNIT NUMBER #XY_DA_V_DS,- #XY_DA_S_DS,- R2 ;**** DM DISPATCHES VIA CASE ;**** THIS COUNTS ON IO$_XXXX RETAINING RELATIVE VALUE ;**** ACCROSS VMS RELEASES. I DON'T BELIEVE IT, SO I ;**** DISPATCH ELSEWISE CMPB #CDF_SEEK,R3 ;IF SEEK BEQL POSIT ; POSITION CMPB #CDF_RECAL,R3 ;IF RECAL BEQL POSIT ; POSITION CMPB #CDF_DRVCLR,R3 ;IF DRVCLR BEQL IMMED ; IMMEDIATE CMPB #CDF_SCLR,R3 ;IF SCLR BEQL IMMED ; IMMEDIATE BRW XFER ;TRANSFER FUNCTION .DSABL LSB ; ; IMMEDIATE FUNCTION EXECUTION ; ; FUNCTIONS INCLUDE: ; ; SYSTEM CLEAR ; DRIVE CLEAR ; ; INTERRUPTS ARE LOCKED OUT, THE APPROPRIATE FUNCTION IS INITIATED WITH ; INTERRUPT ENABLE, AND A WAITFOR INTERRUPT AND KEEP CHANNEL IS EXECUTED. ; ; THESE FUNCTIONS ALL EXECUTE WITHIN A VERY SHORT TIME (15 US), BUT ARE ; VERY INFREQUENT AND THEREFORE ARE DONE WITH INTERRUPTS TO AVOID AN EXTRA ; SET OF REGISTER SAVE LOGIC. ; IMMED: ;IMMEDIATE FUNCTION EXECUTION DSBINT ;DISABLE INTERRUPTS BBS #UCB$V_POWER,UCB$W_STS(R5),ENBXIT ;IF SET, POWER HAS FAILED MOVW R2,XY_DA(R4) MOVW FTAB[R3],XY_CSR(R4) ;EXECUTE FUNCTION BRW ENBXIT ; ; ; POSITIONING FUNCTION EXECUTION ; ; FUNCTIONS INCLUDE: ; ; SEEK CYLINDER, ; RECALIBRATE ; ; THE OFFSET REGISTER AND CYLINDER ADDRESS REGISTERS ARE LOADED, INTERRUPTS ; ARE LOCKED OUT, AND THE APPROPRIATE POSITIONING FUNCTION IS INITIATED ; WITHOUT INTERRUPT ENABLE. THE CONTROLLER IS THEN POLLED FOR READY, DEVICE ; INTERRUPTS ARE ENABLED, AND A WAITFOR INTERRUPT AND RELEASE CHANNEL IS ; EXECUTED. ; POSIT: ;POSITIONING FUNCTION DSBINT ;DISABLE INTERRUPTS BBC #UCB$V_POWER,UCB$W_STS(R5),ENBXIT ;IF SET, POWER HAS FAILED ADDW3 UCB$W_CYL0(R5),UCB$W_DC(R5),XY_DC(R4) ;SET PHY CYL MOVW R2,XY_DA(R4) ;SET UNIT NUMBER MOVW FTAB[R3],XY_CSR(R4) ;EXECUTE FUNCTION WFIKPCH RLSCHN,#60 ;WAITFOR INTERRUPT IOFORK ;CREATE FORK PROCESS BRW RLSCHN ; ENBXIT: ; ENBINT ; BRW RLSCHN ; .PAGE .SBTTL TRANSFER FUNCTION EXECUTION ; ; TRANSFER FUNCTION EXECUTION ; ; FUNCTIONS INCLUDE: ; ; WRITE CHECK, ; WRITE DATA, ; WRITE HEADERS, ; WRITE HEADER, DATA, CRC ; WRITE OVER PROTECTED SECTOR ; READ DATA, AND ; READ HEADER. ; READ IGNORING HEADER AND CRC CHECKS ; ; REGISTER USAGE: ; R2 = UNIT # IN POSITION FOR XY_DA (USH) ; R3 = CEX ; R4 = CSR ; R5 = UCB ; ; A UNIBUS DATAPATH IS REQUESTED FOLLOWED BY THE APPROPRIATE NUMBER OF MAP ; REGISTERS REQUIRED FOR THE TRANSFER. THE TRANSFER PARAMETERS ARE LOADED ; INTO THE DEVICE REGISTERS, INTERRUPTS ARE LOCKED OUT, THE FUNCTION IS ; INITIATED, AND A WAITFOR INTERRUPT AND KEEP CHANNEL IS EXECUTED. ; XFER: ;TRANSFER FUNCTION EXECUTION ; SET SBI <=> UNIBUS REQDPR ;REQUEST DATAPATH REQMPR ;REQUEST MAP REGISTERS TSTL @UCB$L_SVAPTE(R5) ;BAD SVAPTE? BNEQ 1$ ; NEQ => NO BUG_CHECK BADPAGTYPE ; ELSE BUGCHECK 1$: LOADUBA ;LOAD UNIBUS MAP REGISTERS ; SET XY_DA CLRL R2 INSV UCB$W_REALUNIT(R5),- ;INSERT UNIT NUMBER #XY_DA_V_DS,- #XY_DA_S_DS,- R2 BISB UCB$W_DA(R5),R2 ;INSERT SECTOR MOVZBL UCB$W_DA+1(R5),R1 ;GET DESIRED HEAD NUMBER ASHL #7,R1,R1 ;POSITION HEAD NUMBER BISW R1,R2 ; AND INSERT IT MOVW R2,XY_DA(R4) ;GIVE IT TO THE CONTROLLER ; SET XY_WC MOVZWL UCB$W_BCNT(R5),R0 ;GET TRANSFER BYTE COUNT DIVL #2,R0 ;CALCULATE TRANSFER WORD COUNT DSBINT UCB$B_DIPL(R5) ;DISABLE DEVICE INTERRUPTS MNEGW R0,XY_WC(R4) ;SET TRANSFER WORD COUNT ; SET XY_BA MOVZWL UCB$W_BOFF(R5),R0 ;GET BYTE OFFSET IN PAGE MOVL UCB$L_CRB(R5),R1 ;GET ADDRESS OF CRB INSV CRB$L_INTD+VEC$W_MAPREG(R1),#9,#7,R0 ;INSERT HIGH 7 BITS OF ADDRESS MOVW R0,XY_BA(R4) ;SET BUFFER ADDRESS EXTZV #7,#2,CRB$L_INTD+VEC$W_MAPREG(R1),R0 ;GET MEMORY EXTENSION BITS ; SET XY_DC ADDW3 UCB$W_CYL0(R5),UCB$W_DC(R5),XY_DC(R4) ;SET PHY CYL ; SET UP FOR XY_CSR BICW #^CXY_CSR_M_SKI,UCB$W_XY_CSR(R5) ASHL #12,R0,R0 ;SHIFT LEFT 12 BITS INSV UCB$W_OFFSET(R5),- #XY_CSR_V_OFF,- #XY_CSR_S_OFF,- R0 ;SET OFFSET VALUE BISW FTAB[R3],R0 ;MERGE FUNCTION CODE BISW R0,UCB$W_XY_CSR(R5) ;MERGE WITH SEEK INH. ;*******************INTERRUPTS DISABLED******************************** SETIPL #31 ;DISABLE INTERRUPTS BBC #UCB$V_POWER,UCB$W_STS(R5),10$ ;IF CLR, NO POWER FAILURE ENBINT ;ENABLE INTERRUPTS BRW 60$ ; 10$: MOVW UCB$W_XY_CSR(R5),XY_CSR(R4) ;EXECUTE FUNCTION ;**********************INTERRUPTS ENABLED AGAIN************************ WFIKPCH 61$,#60 ;WAITFOR INTERRUPT AND KEEP CHANNEL BRW 62$ 61$: BISW3 #XY_CSR_M_CERR,XY_CSR(R4),UCB$W_XY_CSR(R5) ;SAVE CSR MOVAB XY_DA(R4),R2 ;GET ADR OF D.A. REG MOVAB UCB$W_XY_DA(R5),R3 ;GET ADR OF D.A. SAVE AREA MOVW (R2)+,(R3)+ ;SAVE XY_DA MOVW (R2)+,(R3)+ ;SAVE XY_BA MOVW (R2)+,(R3)+ ;SAVE XY_WC MOVW (R2)+,(R3)+ ;SAVE XY_DC MOVW (R2)+,(R3)+ ;SAVE XY_DS MOVW (R2)+,(R3)+ ;SAVE XY_ER MOVW #F_SCLR!1,XY_CSR(R4) ;CLEAR CONTROLLER TO STOP INT. MOVZBW #XY_CSR_M_IE,XY_CSR(R4) ;RESET INTERRUPT ENABLE 62$: IOFORK ;CREATE FORK PROCESS MOVL UCB$L_CRB(R5),R3 ;GET ADDRESS OF CRB MOVL @CRB$L_INTD+VEC$L_ADP(R3),R2 ;GET ADDRESS OF CONFIGURATION REGISTER EXTZV #VEC$V_DATAPATH,#VEC$S_DATAPATH,- ;EXTRACT DATAPATH NUMBER CRB$L_INTD+VEC$B_DATAPATH(R3),R1 ; ASHL #UBA$V_DPR_BNE,#1,UBA$L_DPR(R2)[R1] ;PURGE DATAPATH ASHL #31-UBA$V_DPR_XMTER,UBA$L_DPR(R2)[R1],R0 ;ANY TRANSMISSION ERROR? BGEQ 20$ ;IF GEQ NO MOVL UBA$L_DPR(R2)[R1],UBA$L_DPR(R2)[R1] ;CLEAR DPPE BISW #XY_CSR_M_CERR,- ;SET CONTROLLER ERROR UCB$W_XY_CSR(R5) CLRW UCB$W_XY_ER(R5) ;CLEAR ERROR REGISTER CLRW UCB$W_XY_DS(R5) ;CLEAR DISK STATUS REGISTER 20$: BBS #XY_CSR_V_CERR,UCB$W_XY_CSR(R5),30$ ;IF SET , DEVICE ERRORS BBC #UCB$V_DIAGBUF,UCB$W_DEVSTS(R5),40$ ;IF CLR, NO DIAGNOSTIC BUFFER ; HERE ON DEVICE ERROR OR DIAGNOSTIC BUFFER PRESENT 30$: MOVW R1,UCB$W_XY_DPN(R5) ;SAVE DATAPATH NUMBER MOVL UBA$L_DPR(R2)[R1],UCB$L_XY_DPR(R5) ;SAVE DATAPATH REGISTER EXTZV #9,#7,UCB$W_XY_BA(R5),R0 ;GET LOW BITS OF FINAL MAP REGISTER NUMBER EXTZV #XY_CSR_V_MEX,- #XY_CSR_S_MEX,- UCB$W_XY_CSR(R5),R1 ;GET HIGH BITS OF FINAL MAP REG. INSV R1,#7,#2,R0 ;INSERT HIGH BITS OF FINAL MAP REGISTER CMPW #495,R0 ;LEGAL MAP REGISTER NUMBER? BGEQ 35$ ;IF GEQ YES MOVZWL #495,R0 ;RESTRICT MAP REGISTER NUMBER 35$: MOVL UBA$L_MAP(R2)[R0],UCB$L_XY_FMPR(R5) ;SAVE FINAL MAP REGISTER CLRL UCB$L_XY_PMPR(R5) ;CLEAR PREVIOUS MAP REGISTER CONTENTS DECL R0 ;CALCULATE PREVIOUS MAP REGISTER NUMBER CMPV #VEC$V_MAPREG,#VEC$S_MAPREG,- ;ANY PREVIOUS MAP REGISTER? CRB$L_INTD+VEC$W_MAPREG(R3),R0 ; BGTR 40$ ;IF GTR NO MOVL UBA$L_MAP(R2)[R0],UCB$L_XY_PMPR(R5) ;SAVE PREVIOUS MAP REGISTER ; HERE IN ANY CASE 40$: MULW3 #2,UCB$W_XY_WC(R5),UCB$W_BCR(R5) ;CONVERT WORD COUNT TO BYTE COUNT ;AND FALL THROUGH TO RELEASE DPR ; HERE IN ANY CASE 60$: RELDPR ;RELEASE DATA PATH RELMPR ;RELEASE MAP REGISTERS RLSCHN: ; RELCHAN ;RELEASE CHANNEL ; ; RETURN REGISTERS ; .ENABL LSB RETREG: ;RETURN FINAL DEVICE REGISTERS MOVZWL UCB$W_XY_CSR(R5),R1 ;RETRIEVE CONTROL STATUS REGISTER MOVZWL UCB$W_XY_DS(R5),R2 ;RETRIEVE DISK STATUS REGISTER MOVZWL UCB$W_XY_ER(R5),R3 ;RETRIEVE ERROR REGISTER BITW #UCB$M_POWER!- ;POWER FAIL OR DEVICE TIMEOUT? UCB$M_TIMOUT,UCB$W_STS(R5) ; BNEQ 30$ ;IF NEQ YES - SPECIAL CONDITION BBC #XY_CSR_V_CERR,R1,10$ ;IF CLR, NO ERRORS BBS #XY_ER_V_DLT,R3,7$ ;IF SET, JUST DATA LATE, DON'T FILL E.L. JSB G^ERL$DEVICERR ;ALLOCATE AND FILL ERROR MESSAGE BUFFER BBS #IO$V_INHRETRY,UCB$W_FUNC(R5),20$ ;IF SET, RETRY INHIBITED BITW #XY_ER_M_BSE!- ;BAD SECTOR ERROR OR, XY_ER_M_COE!- ;CYLINDER ADDRESS OVERFLOW OR, XY_ER_M_IHAE!- ;INVALID HEADER ADDR ERROR OR, XY_ER_M_ISAE!- ;INVALID SECTOR ADDR ERROR OR, XY_ER_M_ICAE!- ;INVALID CYLINDER ADDR ERROR OR, XY_ER_M_WLE,R3 ;WRITE LOCK ERROR? BNEQ 20$ ;IF NEQ YES ; ; RETRIABLE ERROR EXIT ; ; RETURN TO FEX CALL OR DISPLACEMENT THEREFROM STORED IN NEXT BYTE ; 7$: MOVZBL @UCB$L_DPC(R5),-(SP) ;GET BRANCH DISPLACEMENT ADDL (SP)+,UCB$L_DPC(R5) ;CALCULATE RETURN ADDRESS - 1 10$: INCL UCB$L_DPC(R5) ;ADJUST TO CORRECT RETURN ADDRESS JMP @UCB$L_DPC(R5) ;RETURN TO DRIVER ; ; FATAL CONTROLLER OR DRIVE ERROR EXIT ; 20$: BRW FATALERR ; ; ; SPECIAL CONDITION (POWER FAILURE OR DEVICE TIME OUT) ; 30$: BBSC #UCB$V_POWER,UCB$W_STS(R5),50$ ;IF SET, POWER FAILURE ; ; DEVICE TIME OUT ; JSB G^ERL$DEVICTMO ;LOG DEVICE TIME OUT MOVL UCB$L_CRB(R5),R3 ;GET ADDRESS OF CRB MOVL CRB$L_INTD+VEC$L_IDB(R3),R3 ;GET ADDRESS OF IDB CMPL R5,IDB$L_OWNER(R3) ;DEVICE OWN CONTROLLER? BNEQ 40$ ;IF NEQ NO MOVW #F_SCLR!1,XY_CSR(R4) ;CLEAR ENTIRE XYLOGICS SUBSYSTEM MOVZBW #XY_CSR_M_IE,XY_CSR(R4) ;ENABLE DEVICE INTERRUPTS 40$: SETIPL UCB$B_FIPL(R5) ;LOWER TO FORK LEVEL MOVZWL #SS$_TIMEOUT,R0 ;SET DEVICE TIMEOUT STATUS DECB UCB$B_ERTCNT(R5) ;ANY ERROR RETRIES REMAINING? BEQL RESETXFR ;IF EQL NO RELCHAN ;RELEASE CHANNEL IF OWNED BICW #UCB$M_TIMOUT,UCB$W_STS(R5) ;CLEAR TIME OUT STATUS BRW FDISPATCH ; ; ; RESET TRANSFER BYTE COUNT TO ZERO ; RESETXFR: ; MOVL UCB$L_IRP(R5),R3 ;RETRIEVE ADDRESS OF I/O PACKET MNEGW IRP$W_BCNT(R3),UCB$W_BCR(R5) ;RESET TRANSFER BYTE COUNT BRW FUNCXT ; ; ; POWER FAILURE ; 50$: RELCHAN ;RELEASE CHANNEL IF OWNED MOVL UCB$L_IRP(R5),R3 ;RETRIEVE ADDRESS OF I/O PACKET MOVQ IRP$L_SVAPTE(R3),UCB$L_SVAPTE(R5) ;RESTORE TRANSFER PARAMETERS BRW XY_STARTIO ; .DSABL LSB .PAGE .SBTTL XYLOGICS-CDC REGISTER DUMP ROUTINE ; ; XY_REGDUMP - XYLOGICS-CDC 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 CONTROL STATUS REGISTER 1. ; R5 = DEVICE UNIT UCB ADDRESS. ; ; OUTPUTS: ; ; THE CONTROLLER AND DRIVE REGISTERS ARE SAVED IN THE SPECIFIED BUFFER. ; XY_REGDUMP: ;XYLOGICS-CDC REGISTER DUMP ROUTINE MOVL #11,(R0)+ ;INSERT NUMBER OF DEVICE REGISTERS MOVAL UCB$W_XY_CSR(R5),R1 ;GET ADDRESS OF SAVED DEVICE REGISTERS MOVL #8,R2 ;SET NUMBER OF REGISTERS TO MOVE 10$: MOVZWL (R1)+,(R0)+ ;MOVE REGISTER TO BUFFER SOBGTR R2,10$ ;ANY MORE TO MOVE? MOVL (R1)+,(R0)+ ;INSERT DATAPATH REGISTER MOVL (R1)+,(R0)+ ;INSERT FINAL MAP REGISTER MOVL (R1),(R0)+ ;INSERT PREVIOUS MAP REGISTER RSB ; .PAGE .SBTTL CDC DISK DRIVE INITIALIZATION ; ; XY_CDC_INIT - CDC DISK DRIVE INITIALIZATION ; ; THIS ROUTINE IS CALLED AT SYSTEM INITIALIZATION AND AT POWER RECOVERY TO SET ; DRIVE PARAMETERS AND TO WAIT FOR ONLINE DRIVES TO SPIN UP. ; ; INPUTS: ; ; R4 = ADDRESS OF CONTROL STATUS REGISTER 1. ; R5 = DEVICE UNIT UCB ADDRESS. ; ; OUTPUTS: ; ; UNIT PARAMETERS ARE ESTABLISHED AND THE DRIVE IS SPUN UP IF IT WAS ONLINE. ; XY_CDC_INIT: ;CDC UNIT INITIALIZATION MOVB S^#DT$_CDC,UCB$B_DEVTYPE(R5) ;SET CDC DEVTYP REQDPR ;GET A DATAPATH MOVL UCB$L_CRB(R5),R0 ;GET CRB BISL #VEC$M_PATHLOCK,CRB$L_INTD+VEC$B_DATAPATH(R0) ;AND KEEP MOVZWL UCB$W_UNIT(R5),R0 ;GET VIRT UNIT # MOVW TABLE_CYL0[R0],UCB$W_CYL0(R5) ;SET STARTING CYL MOVW TABLE_CYLCNT[R0],UCB$W_CYLINDERS(R5) ;SET CYLINDER COUNT MOVW TABLE_REALUNIT[R0],UCB$W_REALUNIT(R5) ;SET PHY UNIT # MOVL TABLE_MAXBLOCK[R0],UCB$L_MAXBLOCK(R5) ;SET MAX BLOCK # BISW #UCB$M_ONLINE!UCB$M_VALID,UCB$W_STS(R5) ;SET UNIT ONLINE RSB ; TABLE_CYL0: .WORD 7,211,415,619,7,211,415,619 TABLE_CYLCNT: .WORD 204,204,204,204,204,204,204,204 TABLE_REALUNIT: .WORD 0,0,0,0,1,1,1,1 TABLE_MAXBLOCK: .LONG 204*19*32,204*19*32,204*19*32,204*19*32,- 204*19*32,204*19*32,204*19*32,204*19*32 .PAGE .SBTTL XYLOGICS-CDC UNSOLICITED INTERRUPT ROUTINE ; ; XY_UNSOLNT - XYLOGICS-CDC UNSOLICITED INTERRUPT ROUTINE ; ; THIS ROUTINE IS CALLED WHEN AN UNSOLICITED ATTENTION CONDITION IS DETECTED FOR ; AN CDC OR CDC DRIVE. ; ; INPUTS: ; ; R4 = ADDRESS OF CONTROL STATUS REGISTER 1. ; R5 = DEVICE UNIT UCB ADDRESS. ; ; OUTPUTS: ; ; IF VOLUME VALID IS CLEAR, THEN SOFTWARE VOLUME VALID IS CLEARED. THE ; UNIT STATUS IS CHANGED TO ONLINE AND THE DRIVE TYPE AND PARAMETERS ARE ; CLASSIFIED. ; XY_UNSOLNT: ;XYLOGICS-CDC UNSOLICITED INTERRUPT MOVB S^#DT$_CDC,UCB$B_DEVTYPE(R5) ;SET CDC DEVTYP MOVW #109,UCB$W_CYLINDERS(R5) ;SET NUMBER OF CYLS MOVL #109*19*32,UCB$L_MAXBLOCK(R5) ;SET MAX BLK NO. TSTW UCB$W_UNIT(R5) ;UNIT = 0? BEQL 10$ ;EQ => YES MOVB S^#DT$_CDCN,UCB$B_DEVTYPE(R5) ;SET CDCN DEVTYP MOVW #102,UCB$W_CYLINDERS(R5) ;SET NUMBER OF CYLS MOVL #102*19*32,UCB$L_MAXBLOCK(R5) ;SET MAX BLK NO. 10$: BISW #UCB$M_ONLINE,UCB$W_STS(R5) ;SET UNIT ONLINE RSB ; .PAGE .SBTTL XYLOGICS DISK CONTROLLER INTERRUPT DISPATCHER ;+ ; XY$INT - XYLOGICS DISK CONTROLLER INTERRUPT DISPATCHER ; ; THIS ROUTINE IS ENTERED VIA A JSB INSTRUCTION WHEN AN INTERRUPT OCCURS ; ON AN XYLOGICS DISK CONTROLLER. THE STATE OF THE STACK ON ENTRY IS: ; ; 00(SP) = ADDRESS OF IDB ADDRESS. ; 04(SP) = SAVED R0 ; 08(SP) = SAVED R1 ; 12(SP) = SAVED R2. ; 16(SP) = SAVED R3. ; 20(SP) = SAVED R4. ; 24(SP) = SAVED R5. ; 28(SP) = INTERRUPT PC. ; 32(SP) = INTERRUPT PSL. ; ; INTERRUPT DISPATCHING OCCURS AS FOLLOWS: ; ; IF THE INTERRUPTING CONTROLLER IS CURRENTLY OWNED AND THE OWNER ; UNIT IS EXPECTING AN INTERRUPT, THEN THAT UNIT IS DISPATCHED FIRST. ; ALL OTHER UNITS ARE DISPATCHED BY READING THE ATTENTION SUMMARY ; REGISTER AND SCANNING FOR UNITS THAT HAVE ATTENTION SET. AS EACH ; UNIT IS FOUND, A TEST IS MADE TO DETERMINE IF AN INTERRUPT IS ; EXPECTED ON THE UNIT. IF YES, THEN THE DRIVER IS CALLED AT ITS ; INTERRUPT RETURN ADDRESS. ELSE THE DRIVER IS CALLED AT ITS UNSOL- ; ICITED INTERRUPT ADDRESS. AS EACH CALL TO THE DRIVER RETURNS, THE ; ATTENTION SUMMARY REGISTER IS REREAD AND AN ATTEMPT IS MADE TO FIND ; ANOTHER UNIT TO DISPATCH. WHEN NO UNITS REQUESTING ATTENTION REMAIN, ; THE INTERRUPT IS DISMISSED. ;- XY$INT:: ;XYLOGICS DISK CONTROLLER INTERRUPT DISPATCHER MOVL @(SP),R3 ;GET ADDRESS OF IDB MOVL IDB$L_CSR(R3),R4 ;GET ADDRESS OF CONTROL STATUS REGISTER MOVL IDB$L_OWNER(R3),R5 ;GET OWNER UNIT UCB ADDRESS BEQL 10$ ;IF EQL NO OWNER BBSC #UCB$V_INT,UCB$W_STS(R5),30$ ;IF SET, INTERRUPT EXPECTED ; HERE IF NO OWNER, OR OWNER NOT EXPECTING INTERRUPT 10$: ; EVENTUALLY MUST GO THROUGH THIS CODE TO EXIT INTERRUPT ; HERE IF NO MORE SEEK DONE DISKS MOVZBW #XY_CSR_M_IE,XY_CSR(R4) ;ENABLE DEVICE INTERRUPTS ADDL #4,SP ;CLEAN STACK MOVQ (SP)+,R0 ;RESTORE REGISTERS MOVQ (SP)+,R2 ; MOVQ (SP)+,R4 ; REI ; ; HERE IF OWNER EXISTS AND EXPECTS INTERRUPT ; FALL THROUGH TO HERE IF INTERRUPT EXPECTED BY SEEK DONE DISK 30$: MOVAB XY_CSR(R4),R2 ;GET ADDRESS OF CONTROL STATUS REGISTER MOVAB UCB$W_XY_CSR(R5),R3 ;GET ADDRESS OF REGISTER SAVE AREA MOVW (R2)+,(R3)+ ;SAVE CONTROL STATUS REGISTER BLSS 100$ ;IF LSS ERROR ENCOUNTERED BBS #UCB$V_DIAGBUF,UCB$W_DEVSTS(R5),100$ ;IF SET, DIAGNOSTIC BUFFER MOVW (R2)+,(R3)+ ;SAVE DISK ADDRESS REGISTER MOVW (R2)+,(R3)+ ;SAVE BUFFER ADDRESS REGISTER MOVW (R2),(R3) ;SAVE WORD COUNT REGISTER ; REACH HERE WITH NEED TO CALL DRIVER IN STARTIO AT WFIK CALL 50$: MOVQ UCB$L_FR3(R5),R3 ;RESTORE DRIVER CONTEXT JSB @UCB$L_FPC(R5) ;CALL DRIVER AT INTERRUPT RETURN ADDRESS MOVL @(SP),R3 ;GET ADDRESS OF IDB MOVL IDB$L_CSR(R3),R4 ;GET ADDRESS OF CSR CLRL R2 BRW 10$ ; ; REACH HERE IF UNIT DETERMINED AND ERROR EXISTS 100$: MOVW (R2)+,(R3)+ ;SAVE DESIRED SECTOR/TRACK ADDRESS REGISTER MOVW (R2)+,(R3)+ ;SAVE BUFFER ADDRESS REGISTER MOVW (R2)+,(R3)+ ;SAVE WORD COUNT REGISTER MOVW (R2)+,(R3)+ ;SAVE DESIRED CYLINDER ADDRESS REGISTER MOVW (R2)+,(R3)+ ;SAVE DRIVE STATUS REGISTER MOVW (R2)+,(R3)+ ;SAVE ERROR REGISTER JSB XY_CLEAR ;CLEAR THE SYSTEM BRW 50$ ; ; THIS SUBROUTINE CLEARS ALL ERRORS IN SELECTED DRIVE ; CORRECT UCB ADR MUST BE IN R5 ; AND CORRECT UNIT MUST BE IN XY_DA XY_CLEAR: BBC #XY_ER_V_UNS,XY_ER(R4),10$ ;CLEAR => NO DRIVE UNSAFE MOVW #F_DRVCLR!1,XY_CSR(R4) ;CLEAR POSSIBLE DRIVE FAULT 10$: BITW #XY_ER_M_SKI!XY_ER_M_CCE,XY_ER(R4) ;HARD SEEK ERROR? BEQL 20$ ;EQ => NO HARD SEEK ERROR MOVW #F_RECAL!1,XY_CSR(R4) ;CLEAR HARD SEEK ERROR 20$: RSB .PAGE .SBTTL XYLOGICS DISK CONTROLLER INITIALIZATION ;+ ; XY_XYLOG_INIT - XYLOGICS DISK CONTROLLER INITIALIZATION ; ; THIS ROUTINE IS CALLED VIA A JSB INSTRUCTION AT SYSTEM STARTUP AND AFTER ; A POWER RECOVERY RESTART TO ALLOW INITIALIZATION OF XYLOGICS DISK CONTROLLERS. ; ; INPUTS: ; ; R0 = SCRATCH. ; R1 = SCRATCH. ; R2 = SCRATCH. ; R3 = SCRATCH. ; R4 = ADDRESS OF CONTROL STATUS REGISTER 1. ; R5 = ADDRESS OF CONTROLLER IDB. ; ; ALL INTERRUPTS ARE LOCKED OUT. ; ; OUTPUTS: ; ; THE XYLOGICS CONTROLLER IS INITIALIZED AND INTERRUPTS ARE ENABLED. ;- XY_XYLOG_INIT: ;XYLOGICS DISK CONTROLLER INITIALIZATION CLRW XY_DA(R4) ;SELECT UNIT NUMBER MOVW CDF_SCLR,XY_CSR(R4) ;CLEAR CONTROLLER AND DRIVES RSB ; XY_END: ;ADDRESS OF LAST LOCATION IN DRIVER .END