;DRMDDC.MAC 7/2/75 EDIT BY HEATHMAN ;ADDED RECOVERABLE ERROR LOGGING CODE ;DRMDDC.MAC;27 20-JUN-75 11:18:23 EDIT BY CROSSLAND ;ADDED DRUM MIGRATION CODE FROM IMSS ;DRMDDC.MAC 14-FEB-75 EDIT BY HEATHMAN ;CHANGES TO INITIALIZE BAND LOCK OUT CODE ;12 JUL 1974 / RAINER SCHULZ ;DRUM DRIVER - DEC RES-10 CONTROLLER,DDC DISK SEARCH PROLOG TITLE DRM INTERN DRMIO,DRMINI,DRMRST,DRMSV,.DRMOP INTERN CLKDRS,DRMBBT,DRMBST EXTERN FORKX,HLOCKR,STOPLK,DRPI,SWPPI,NOPILK,HLOCKP EXTERN SWPDON,DRUMP,DEVMPE,PRELRQ,DNOGO EXTERN DSKIO,PWRDWN,BITS,BUGHLT,BUGCHK EXTERN MENTR,CAPENB,WHEELX,MRETN,FPTA,BUGMSG EXTERN MLKPG,MULKPG,DISGET,SCHEDP,EDISMS,PSKED EXTERN DSKOP2,DSKOP3 EXTERN DDERLL,DDERST,DDERWD,JB0FLG,DRMEUT,DDERTP,INSKED,DDERBP EXTERN DSKNOV ;CST3 LH CONTROL BITS INTERN DWRBIT,SWPERR DWRBIT==400000 SWPERR==200000 RESCD ;THIS ALLOCATOR HANDLES A DEVICE OF SOME NUMBER (DRMSEC) OF SECTORS, ;AND SOME NUMBER (DRMBND) OF BANDS. IT HAS A RESIDENT BIT TABLE, ;AND IS USED TO ALLOCATE SWAPPING STORAGE, EVEN IF THE PHYSICAL ;SWAPPING DEVICE IS THE SAME AS THE PHYSICAL FILE DEVICE ;THE FOLLOWING ROUTINES ARE IN THIS PACKAGE & CALLED FROM OUTSIDE. INTERN DRMASD ;ASSIGN SWAPPING DISK ADDRESS INTERN ASDRMS ;ASSIGN SPECIFIC DRUM ADDRESSES INTERN DRMASF ;ASSIGN A DRUM PAGE, EMPTIEST SECTOR. INTERN ASDRM ;ASSIGN DRUM PAGE NEAR A SPECIFIC SECTOR INTERN DEDRM ;DEASSIGN A DRUM PAGE INTERN DRMSEC,NDRMEW INTERN STBTWD,CHKDRR INTERN MAXDRM DRUM2=1 ;1 SAYS WE HAVE TWO DRUMS FDRUM==20000 ;END OF FIRST DRUM-MUST BE MAXDRM IF ONE DRUM ONLY DRMSEC==^D13 ;NO. OF DRUM SECTORS DRMBND==NDST/DRMSEC ;NO OF BANDS DRMBSZ==/^D36 ;SIZE OF BIT TABLE CHUNK FOR 1 SECTOR LS DRMBLK,1 ;LOCKOUT WORD FOR DRUM BIT TABLE LS DRBTWD,NDST/^D36+1 ;BIT TABLE FOR RECENTLY REF. DRUM PAGES GS DRMBIT,DRMSEC*DRMBSZ ;DRUM BIT TABLE LS DRMLSA,1 ;LAST SECTOR ASSIGNED ;NOW USED TO HOLD OFFSET INTO BITTABLE OF FIRST FREE SECTOR Z==0 A==1 B==2 C==3 D==4 E==5 F==6 G==7 AA==10 BB==11 CC==12 DD==13 EE==14 FF==15 GG==16 ;DRUM ERROR WORDS NDRMEW==^D18 ;NO OF DRUM ERROR WORDS ; DRMCFE THROUGH DRMFRE MUST BE KEPT TOGETHER LS DRMCFE,1 ;COUNT OF ERRORS LS DRMLER,4 ;LAST DRUM ERROR WORDS LS DRCKER,1 ;DRUM CHECKSUM ERROR LS DCTRER,1 ;COMM. SEQ. ERROR LS DCPAER,1 ;PARITY ERROR(MEM) LS DNXMER,1 ;NXM LS QPAER,1 ;QUEUE PARITY ERROR LS DIPAER,1 ;INTERNAL PARITY ERROR(SILO) LS DOVRER,1 ;OVERRUN LS DTIMER,1 ;DRUM TIMEOUT(HUNG DEVICE) LS QBFER,1 ;QUEUE BUFFER FULL LS EXDER,1 ;EXCEEDED DISK CAPACITY LS DRMRDS,1 ;DRUM READS LS DRMWRS,1 ;DRUM WRITES ;FOLLOWING FOUR ENTRIES MAKE UP SWPSTS TABLE LS DRMFRE,1 ;FREE DRUM PAGES GS DSKFRE,1 ;FREE DISK PAGES LS DRSWCT,1 ;REAL DRUM SWAPS LS DKSWCT,1 ;DISK SWAPS INSTEAD OF DRUM ;DRUM CONO BITS DRMRES==3B19 ;RESET DRMCLT==1B18 ;CLEAR INT DRMCLE==1B19 ;CLEAR ERRORS DRMEXF==1B20 ;EXECUTE FR DRMEXQ==1B21 ;EXECUTE QUEUE ;DRUM CONI BITS DRMQPA==1B0 ;QUEUE PARITY ERROR DRMBUS==1B18 ;DRUM BUSY DRMDON==1B19 ;DRUM DONE FLAG DRMCSE==1B26 ;COMM SEQ. ERROR DRMQF==1B27 ;QUEUE FULL ERROR DRMRDY==1B28 ;DRUM READY DRMSPA==1B29 ;DRUM SILO PARITY ERROR DRMNXM==1B30 ;NXM DRMEXC==1B31 ;EXCEEDED CAPACITY DRMHUD==1B32 ;DRUM HUNG DRMMPE==1B33 ;MPE DRMOVR==1B34 ;DATA OVERRUN DRMCKE==1B35 ;CHECKSUM ERROR ;SOME DRUM ALLOCATION AND DEFINITIONS LS DRMSVR,1 ;INTERRUPT RETURN LOCATION DR0==440 ;DRUM CONTR. ADDRESS 0 FDRF==2 IFE DRUM2, LS DRLOOP,1 ;FOR LOOPING ON DRUMS LS DRLSEC,1 ;LAST DRUM SECTOR IN QUEUE LS DRMFLG,1 ;DRUM INTERRUPT REQ. LS DRMSEQ,1 ;DRUM SEQUENCE NUMBER LS CMDST,1 ;FIRST NON SERVICED COMMAND IN QUEUE LS DRMINT,2 ;SECTORS TO BE SERVICED NPWDS==10 LS QPWA,NPWDS ;PROGRAM QUEUE LS QPWB,NPWDS ;PWB LS DRMSTS,NPWDS ;DRUM COMMAND STATUS ;BYTE POINTERS BPWAC: POINT 3,QPWA(1),2 ;COMMAND BSEQN: POINT 5,QPWA(1),11 ;SEQ. NUMBER BPIA: POINT 3,QPWA(1),14 ;PIA BFUNC: POINT 2,QPWA(1),16 ;FUNCTION BDISC: POINT 2,QPWA(1),18 ;LOGICAL DISC BTRACK: POINT 10,QPWA(1),28 ;TRACK ADDRESS BSECT: POINT 7,QPWA(1),35 ;SECTOR ADDRESS ;BYTE POINTER FOR STATUS FROM DRUM DRSEC: POINT 7,0,17 ;SECTOR COUNTER DRDPA: POINT 5,0,10 ;DONE SEQ. NO. IN STATUS ;BYTE POINTER FOR DRUM COMMAND STATUS (DRMSTS) DRERC: POINT 6,DRMSTS(1),35 ;ERROR RETRY COUNT DRUTS: POINT 6,DRMSTS(1),26 ;UTILITY I/O COMMAND PAIR INDEX NDRMCM=20 ;NUMBER OF POSSILBY QUEUED UTILITY OPS LS DRMCCT,1 ;FREE UTILITY COMMAND PAIR COUNT LS DRMFCL,1 ;START OF FREE UTILITY COMMAND PAIR LIST LS DRMCL,NDRMCM*2 ;UTILITY COMMAND PAIR BUFFERS LS CMDCNT,1 ;COMMANDS IN PROGRESS NRETRY==50 ;50 TRIES ON RECOVERY LS DRMRI,DRMSEC*FDRF ;READ QUEUE INPUT POINTER LS DRMRO,DRMSEC*FDRF ;READ QUEUE OUTPUT POINTER LS DRMWI,DRMSEC*FDRF ;WRITE QUEUE INPUT POINTER LS DRMWO,DRMSEC*FDRF ;WRITE QUEUE OUTPUT POINTER LS DRMPI,DRMSEC*FDRF ;PRELOAD READ QUEUE LS DRMPO,DRMSEC*FDRF LS DRMUI,DRMSEC*FDRF ;UTILITY QUEUE INPUT POINTER LS DRMUO,DRMSEC*FDRF ;UTILITY QUEUE OUTPUT POINTER ;DRUM STARTUP FROM CLOCK INTERRUPT LEVEL LS CLKSVA,1 ;TEMP. SAVE AC3 LS CLKSVB,1 ;TEMP SAVE AC2 LS CLKSVC,1 ;TEMP. SAVE AC1 CLKDRS: SKIPN DRMINT IFN DRUM2, JRST 0(1) SKIPN CMDCNT ;DRUM BUSY CONSZ PI,1B<20+DRMCHN> ;ON DRUM INTERRUPT LEVEL JRST 0(1) MOVEM 1,CLKSVC ;SAVE AC1 MOVEM 3,CLKSVA MOVEM 2,CLKSVB SETZM DRLOOP SKIPN DRMINT ;FIRST DRUM READY JRST CLKDR3 ;NO SETZM DRLSEC JSP 3,DRMNXT ;GET NEXT SECTOR MOVEI 2,1 LSH 2,0(1) TDNE 2,DRMINT ;ANY REQ. JRST [SETZM DRLSEC JRST CLKDR2 ] CLKDR3: SKIPN DRMINT+1 ;SEC. DRUM REQ. JRST CLKDR1 ;NO MOVSI 1,400000 MOVEM 1,DRLSEC JSP 3,DRMNXT SUBI 1,DRMSEC MOVEI 2,1 LSH 2,0(1) TDNN 2,DRMINT+1 ;SEC. DRUM READY JRST CLKDR1 ;NO MOVSI 2,400000 MOVEM 2,DRLSEC CLKDR2: AOS DRMFLG ;FLAG INTERR. REQ. ISB DRMCHN CLKDR1: MOVE 3,CLKSVA MOVE 2,CLKSVB MOVE 1,CLKSVC JRST 0(1) ;RETURN ;DRUM OPERATE JSYS - USER UTILITY DRUM HANDLE .DRMOP: JSYS MENTR CALL DSKOP2 ;DO SAME PAGE SETUP AS IN DSK.MAC UMOVE 1,1 ;GET DRUM ADDRESS CALL UDRMIO ;OPERATE THE DRUM JRST DSKOP3 ;AND RETURN LIKE DSKOP ;DRUM UTILITY I/O DRIVER ;AC1 - TENEX INTERNAL DRUM ADDRESS ;AC2 - 1B14 = WRITE ; 1B1 = NO RETRY ON ERRORS ; RH = WORD COUNT ;AC3 - REAL CORE ADDRESS ; IF NOT IN SCHED, RETURNS +1 WITH CONI ERROR BITS. ; IF IN SCHED, RETURNS +1 IF COULD NOT GET COMMAND WORD PAIR ; RETURNS +2 IF COMMAND QUEUED UP WITH COMMAND WORD PAIR POINTER IN 1 UDRMIO: SOSGE DRMCCT ;COMMAND BUFFER FULL JRST [AOS DRMCCT ;CORRECT COUNT SKIPE INSKED ;IN SCHED? RET ;YES, TAKE ERROR EXIT PUSH P,1 ;YES, WAIT MOVEI 1,UDRM2 ;DISMISS UNTIL ROOM IN COMMAND LIST JSYS EDISMS POP P,1 JRST UDRMIO] NOSKD1 HLOCKI DRPI ;LOCK QUEUE MOVE 4,@DRMFCL ;GET A COMMAND PAIR EXCH 4,DRMFCL HULOCK DRPI ;UNLOCK QUEUE OKPI HLL 3,2 ;GET BITS WITH CORE ADDRESS TLZ 3,577777 ;MASK OUT IRRELEVENT BITS TLNE 2,(1B14) TLO 3,(1B16) ;WRITE TLNN 2,(1B14) TLO 3,(2B16) ;NO, MAKE READ FUNCTION MOVEM 3,1(4) MOVEI 2,(2) ;GET JUST SECTOR COUNT LSH 2,-7 ;DIVIDE BY 200 WORDS/SECTOR JUMPE 2,UDRM3 ;SAY 0 SECTORS ILLEGAL MOVNS 2 DPB 2,[POINT 9,1(4),13] ;SET UP SECTOR COUNT TRO 1,(1B0) ;1B0 INDICATES COMMAND NOT YET EXECUTED HRLZM 1,0(4) ;SET IN DRUM ADDRESS TRZ 1,(1B0) MOVEI 1,(1) ;MASK OFF IRELEVANT BITS IDIVI 1,100 ;GET SECTOR IN 2, TRACK IN 1 LSH 1,-7 ;GET DRIVE CAIL 1,FDRF ;LEGAL DRIVE? JRST UDRM3 ;NO CAIL 2,DRMSEC ;LEGAL SECTOR? JRST UDRM3 ;NO MOVEI 3,DRMSEC ;GET DRUM*SECTORS IMUL 3,1 ADD 3,2 ;GET RIGHT DRUM/SECTOR QUEUE HLOCKI DRPI HRRM 4,@DRMUI(3) ;QUEUE UTILITY REQUEST HRRZM 4,DRMUI(3) HULOCK DRPI ;UNLOCK QUEUE OKPI MOVEI 3,1 LSH 3,(2) IORM 3,DRMINT(1) ;SET SECTOR INT REQ FLAG OKSKD1 SKIPE INSKED ;IN SCHED? JRST UDRM5 ;YES MOVEI 1,DISGET HRLI 1,0(4) ;TEST SECOND WORD OF COMMAND PAIR FOR .GE. 0 JSYS SCHEDP NOSKED MOVE 1,1(4) ;GET ERROR BITS UDRM4: HLOCKI DRPI ;LOCK QUEUE EXCH 4,DRMFCL ;RETURN PAIR TO FREE LIST MOVEM 4,@DRMFCL AOS DRMCCT ;ADD FREE COMMAND PAIR BACK INTO COUNT HULOCK DRPI ;UNLOCK QUEUE OKPI OKSKED RET UDRM2: SKIPG DRMCCT ;ANY ROOM NOW? JRST 0(4) ;NO JRST 1(4) ;YES UDRM3: SETO 1, ;ILLEGAL ADDRESS ERROR SKIPN INSKED ;FROM SCHED? JRST UDRM4 ;NO MOVEM 1,1(4) ;YES, FAKE BAD OP SETZM 0(4) UDRM5: MOVE 1,4 AOS (P) RET UDRMSW: SKIPGE 0(1) ;TEST FO COMMAND COMPLETION JRST 0(4) ;NOT YET MOVE 2,1(1) ;GET CONI BITS HLOCKI DRPI ;LOCK QUEUE EXCH 1,DRMFCL ;PUT COMMAND PAIR BACK ON QUEUE MOVEM 1,@DRMFCL AOS DRMCCT ;ADD TO QUEUE COUNT HULOCK DRPI ;UNLOCK QUEUE OKPI MOVE 1,2 ;RETURN ERROR BITS JRST 1(4) ;SAY COMMAND FINISHED ;DRUM DRIVER ;AC1/18-35 CORE PAGE NUMBER (CST INDEX) OF PAGE ; WRITE OPERATION IF 1, READ IF 0 ;IF ADDRESS IS > = MAXDRM THEN GO TO DSKIO DRMIO: SKIPG DRUMP ; DRUM AVAILABLE JRST DSKIO ; NO HRRZ 2, CST1(1) CAML 2, MAXDRM DRMOP3: JRST [ AOS DKSWCT ;NOT REAL DRUM SWAP-TO DISK JRST DSKIO ] AOS DRSWCT ;COUNT REAL DRUM SWAPS PUSH P, 1 CAIL 2,FDRUM JRST [ ANDI 2,77 ADDI 2,DRMSEC ;SECOND DRUM JRST .+2 ] ANDI 2, 77 ; GET SECTOR NUMBER ADDI 1, CST3 HLLZM 1, 0(1) ; STORE WRITE BIT, 0 MARKS LAST WORD HLOCKI DRPI ;LOCK QUEUE JUMPL 1, [HRRM 1, @DRMWI(2) HRRZM 1, DRMWI(2) AOS DRMWRS ;NO OF DRUM WRITES JRST DRMOP2] SKIPE PRELRQ ;PRELOADING JRST DRMOP4 ;YES HRRM 1, @DRMRI(2) ;UPDATE READ QUEUES HRRZM 1, DRMRI(2) DRMOP5: AOS DRMRDS ;NO OF DRUM READS DRMOP2: HULOCK DRPI ;UNLOCK QUEUE OKPI PUSH P,3 SETZ 3,0 CAIL 2,DRMSEC JRST [ MOVEI 3,1 SUBI 2,DRMSEC JRST .+1 ] MOVEI 1,1 LSH 1,0(2) IORM 1,DRMINT(3) ;SET SECTOR INT. REQ. FLAG POP P,3 POP P, 1 RET DRMOP4: HRRM 1,@DRMPI(2) HRRZM 1,DRMPI(2) JRST DRMOP5 ; INTERRUPT ROUTINE DRMSV: XWD DRMSVR, .+1 ; CALLED BY JSYS IN PISRV DATAI DR0,0 SKIPN DRMFLG ;CLOCK LEVEL INT REQ SKIPGE 0 ;DRUM INT. ON JRST .+2 JRST @DRMSVR ;NOT DRUM IFN KIFLG, SETZM DRMFLG SKIPE PWRDWN ;POWER DOWN JRST [ CONO DR0,DRMRES ;RESET DRUM JRST DRMINX ] ;EXIT FROM DRUM CONO DR0,DRMCLT ;CLEAR DRUM INT. CONI DR0,0 ;READ STATUS INTO 0 SKIPN CMDCNT ;DRUM ACTIVE JRST DRMSV1 ;NO TRY TO START TDNE 0,[DRMQPA+DRMCSE+DRMQF+177] ;DRUM ERRORS JRST DRMERR MOVE 1,CMDST ;FIRST CLEANUP COMMAND DRMSV3: SKIPN CMDCNT BUG(HLT,) SKIPN QPWA(1) ;ANYTHING THERE BUG(HLT,) JSP 4,DRMSV8 ;GO CHECK FOR UTILITY OR SWAPPER MOVE 2,CMDST AOS 1,CMDST CAIL 1,NPWDS ;WRAP AROUND SETZB 1,CMDST LDB 3,DRDPA ;GET DRUM SEQ. NUMBER CAIE 3,0(2) JRST DRMSV3 ;TRY FOR MORE CLEANUP DRMSV1: MOVE 2,CMDCNT ;START LOOKING FOR MORE COMM. CAIL 2,2 ;DONT PUT OUT MORE THAN 3 JRST DRMINX ;ENOUGH ALREADY SETZM DRLOOP DRMSV5: JSP 3,DRMNXT ;GET NEXT SECTOR HLOCK DRPI ;LOCK DRUM QUEUES HLOCKI SWPPI SKIPE 2,DRMUO(1) ;UTILITY QUEUE JRST DRMUQ SKIPE 2,DRMRO(1) ;READ QEUE JRST DRMIQ SKIPE 2,DRMPO(1) ;PRELOAD QUEUE JRST DRMPQ SKIPE 2,DRMWO(1) ;WRITE QUEUE JRST DRMSV2 HULOCK SWPPI OKPI SETZ 3,0 CAIL 1,DRMSEC JRST [ SUBI 1,DRMSEC MOVEI 3,1 JRST .+1 ] MOVEI 2,1 LSH 2,0(1) ANDCAM 2,DRMINT(3) ;REMOVE INT. REQ. FLAG HULOCK DRPI SKIPE DRLOOP JRST DRMINX ;EXIT AOS DRLOOP JRST DRMSV5 DRMSV2: HRRZ 2,0(2) JUMPN 2,.+3 MOVEI 3,DRMWO(1) MOVEM 3,DRMWI(1) EXCH 2,DRMWO(1) DRM4SV: HULOCK SWPPI HULOCK DRPI ;UNLOCK QUEUES OKPI AOS 1,DRMSEQ ;GET NEXT SEQ NUMBER CAIL 1,NPWDS SETZB 1,DRMSEQ ;WRAP AROUND SKIPE QPWA(1) ;THIS ENTRY SHOULD BE AVAIL. BUG(HLT,) SKIPN CMDCNT MOVEM 1,CMDST ;INIT. FIRST DRUM RETURN SUBI 2,CST3 ;GET PAGE NO SKIPL 2 ;IF ILLEGAL PAGE #, CAIL 2,1000 ;MUST BE JRST DRMSV6 ;UTILITY OP MOVEI 3,0(2) LSH 3,11 ;MAKE ACTUAL ADDRESS TLO 3,617700 ;SET SECTOR COUNT. ,PWB MOVEM 3,QPWB(1) MOVSI 4,DWRBIT MOVEI 3,2 TDNE 4,CST3(2) ;TRYING TO WRITE MOVEI 3,1 ;YES HRRZ 4,CST1(2) ;GET DRUM ADDRESS DRMSV7: DPB 3,BFUNC ;SET FUNCTION DPB 1,BSEQN ;SEQ. NO. MOVEI 3,DRMCHN DPB 3,BPIA ;PIA MOVEI 3,5 DPB 3,BPWAC ;PWA ADDR. MOVE 3,4 ;GET DRUM ADDRESS CAIL 3,FDRUM ;FIRST DRUM JRST [ANDI 3,77 TLO 3,(1B0) JRST .+2 ] ANDI 3,77 MOVEM 3,DRLSEC ;LAST DRUM SECTOR ADDRESSED LSH 3,2 DPB 3,BSECT ;SET SECTOR MOVE 3,4 ;GET DRUM ADDRESS CAIL 3,FDRUM JRST [SUBI 3,FDRUM JRST .+1 ] LSH 3,-6 DPB 3,BTRACK ;TRACK SKIPGE DRLSEC JRST [MOVEI 3,400000 IORM 3,QPWA(1) JRST .+1 ] DATAO DR0,QPWA(1) DATAO DR0,QPWB(1) SKIPN CMDCNT CONO DR0,DRMEXQ ;START DRUM AOS CMDCNT ;ONE MORE COMMAND JRST DRMSV1 ;TRY FOR MORE DRMINX: UNBRK DRM ;RETURN FROM INTERRUPT ;UTILITY OPERATION DRMSV6: ADDI 2,CST3 ;GET COMMAND PAIR INDEX NUMBER SUBI 2,DRMCL-2 ;(MACRO DOESN'T LIKE CST3-DRMCL+2) LSH 2,-1 DPB 2,DRUTS ;SET INDEX TO SAY THIS IS UTILITY OP LSH 2,1 ADDI 2,DRMCL-2 ;TURN BACK INTO ADDRESS MOVE 3,1(2) ;GET PWB TLZ 3,760017 ;MASK OFF IRRELEVANT BITS TLO 3,(6B2) ;SET IN PWB CODE MOVEM 3,QPWB(1) ;SAVE PWB LDB 3,[POINT 2,1(2),16] ;GET FUNCTION HLRZ 4,0(2) ;GET ADDRESS TRZ 4,(1B0) ;TURN OFF "NOT YET EXECUTED" BIT JRST DRMSV7 DRMSV8: LDB 2,DRUTS ;GET UTILITY INDEX NO. SETZM QPWA(1) ;RESET STUFF SETZM DRMSTS(1) SOS CMDCNT JUMPE 2,[LDB 1,[POINT 9,QPWB(1),26] ;NOT UTILITY OP, SWAPPER JRST SWPDON] LSH 2,1 ;CONVERT TO COMMAND PAIR POINTER MOVSI 3,(1B0) ANDCAM 3,DRMCL-2(2) ;TURN OFF "NOT YET EXECUTED" BIT SETZM DRMCL-2+1(2) ;AND SAY "NO ERRORS" JRST (4) DRMIQ: HRRZ 2, 0(2) ; REMOVE ENTRY FROM READ QUEUE JUMPN 2, .+3 MOVEI 3, DRMRO(1) MOVEM 3, DRMRI(1) EXCH 2, DRMRO(1) JRST DRM4SV DRMPQ: HRRZ 2,0(2) JUMPN 2,.+3 MOVEI 3,DRMPO(1) MOVEM 3,DRMPI(1) EXCH 2,DRMPO(1) JRST DRM4SV DRMUQ: HRRZ 2,0(2) JUMPN 2,.+3 MOVEI 3,DRMUO(1) MOVEM 3,DRMUI(1) EXCH 2,DRMUO(1) JRST DRM4SV ;FIGURE NEXT BEST SECTOR DRMNXT: SKIPE DRLOOP ;SECOND TIME JRST DRMNX3 ;YES SKIPE CMDCNT ;DRUM ALREADY BUSY JRST DRMNX1 ;YES DRMNX3: SETZ 1,0 SKIPGE DRLSEC MOVEI 1,1 CONO DR0,0(1) DATAI DR0,1 ;READ SECTOR SKIPE DRLOOP ADDI 1,4 ADDI 1,2 ANDI 1,177 LSH 1,-2 ;MAKE PAGE DRMNX2: ADDI 1,1 CAILE 1,DRMSEC-1 SUBI 1,DRMSEC SKIPGE DRLSEC ADDI 1,DRMSEC IFN DRUM2, JRST 0(3) DRMNX1: HRRZ 1,DRLSEC ;PICK UP LAST SECTOR JRST DRMNX2 ; ERROR CONDITIONS DRMERR: AOS DRMCFE ; COUNT ERRORS MOVE 2,CMDST DRMER3: LDB 1,DRDPA CAIN 2,0(1) ;TRY CLEANUPOF COMM. BEFORE ERR. JRST DRMER1 ;NO MORE SKIPN CMDCNT BUG(HLT,) SKIPN QPWA(2) ;ANYTHING THERE BUG(HLT,) MOVE 1,2 ;MOVE SEQ. NO. INTO 1 FOR DRMSV8 JSP 4,DRMSV8 ;GO CHECK FOR UTILITY OR SWAPPER DRMER2: AOS 2,CMDST CAIL 2,NPWDS SETZB 2,CMDST JRST DRMER3 ;TRY AGAIN DRMER1: MOVEM 0,DRMLER+3 MOVE 2,DRMSTS(1) MOVEM 2,DRMLER+2 MOVE 2,QPWA(1) MOVEM 2,DRMLER MOVE 2,QPWB(1) MOVEM 2,DRMLER+1 ;SAVE MEM ADDR. TRNE 0,DRMCSE ;COMM SEQ ERROR JRST [ AOS DCTRER JSR BUGCHK JRST .+1] TDNE 0,[DRMQPA] ;QUEUE PARITY AOS QPAER TRNE 0,DRMQF AOS QBFER ;QUEUE FULL TRNE 0,DRMSPA AOS DIPAER ;SILO PARITY ERROR TRNE 0,DRMNXM AOS DNXMER ;NXM TRNE 0,DRMEXC AOS EXDER ;EXCEEDED CAPACITY TRNE 0,DRMHUD AOS DTIMER ;HUNG DEVICE TRNE 0,DRMMPE AOS DCPAER ;MEM PARITY ERROR TRNE 0,DRMOVR AOS DOVRER ;DATA LATE TRNE 0,DRMCKE AOS DRCKER ;CHECKSUM ERROR LDB 4,DRUTS ;GET UTILITY INDEX JUMPN 4,[LSH 4,1 ;YES, UTILITY OP, MOVSI 2,(1B1) ;IGNORE ERROR RETRYS? TDNE 2,DRMCL-2+1(4) JRST DRMEP1 ;YES, TREAT AS HARD ERROR JRST .+1] ;NO, DO ERROR RETRY LDB 4,DRERC ;GET RETRY COUNT AOJ 4, DPB 4,DRERC ;UPDATE RETRY COUNT CAIN 4,1 ;FIRST ERROR? JSP 3,DRMEL1 ;YES, TRY LOGGING IT CAIL 4,NRETRY JRST DRMEP ;SOLID ERROR MOVE 2,QPWA(1) TLZ 2,(1B0) DATAO DR0,2 ;PUT IN FRA MOVE 2,QPWB(1) TLZ 2,(1B0) DATAO DR0,2 ;PUT IN FRB CONO DR0,DRMCLT ;CLEAR INTERRUPT AGAIN CONO DR0,DRMCLE ;CLEAR ERRORS CONO DR0,DRMEXF ;EXECUTE OUT OF FR JRST DRMINX ;EXIT DRMEP: TRNE 0,DRMMPE ;PERMANENT ERROR JRST [ MOVE 2,[SIXBIT /DRM/] MOVEM 2,DEVMPE ISB APRCHN JRST .+1] LDB 4,DRUTS ;UTILITY OP? JUMPN 4,DRMEP3 ;YES SETZM QPWA(1) SETZM DRMSTS(1) SOS CMDCNT LDB 1,[POINT 9,QPWB(1),26] MOVSI 3,SWPERR IORM 3,CST3(1) JSP 4,SWPDON DRMEP2: CONO DR0,DRMCLT ;CLEAR INT. CONO DR0,DRMCLE ;CLEAR ERRORS AOS 2,CMDST CAIL 2,NPWDS SETZM CMDST SKIPE CMDCNT ;ANY MORE IN QUEUE CONO DR0,DRMEXQ ;YES,START QUEUE AGAIN JRST DRMSV1 ;CONTINUE ; UTILITY OP HARD ERROR DRMEP3: LSH 4,1 ;MAKE INTO COMMAND PAIR POINTER DRMEP1: MOVEM 0,DRMCL-2+1(4) ;SAVE CONI MOVSI 3,(1B0) ;TURN OFF "NOT YET EXECUTED" BIT ANDCAM 3,DRMCL-2(4) SETZM QPWA(1) SETZM DRMSTS(1) SOS CMDCNT JRST DRMEP2 SUBTTL DRUM ERROR LOGGER ; ON FIRST ERROR, LOG STATUS WORDS, AND IF READ, COPY DATA DRMEL1: AOSE DDERLL ;GET ERROR LOGGING CODE JRST (3) ;BUSY LDB 2,DRUTS ;UTILITY OP? SKIPE 2 SKIPA 2,[1B8+@DRMUTD] ;YES MOVE 2,[0B8+@DRMSWD] ;NO MOVEM 2,DDERTP ;IDENTIFY OURSELVES MOVE 2,[DRMCFE,,DDERWD] ;SAVE STATUS WORDS BLT 2,DDERWD+4 LDB 2,BFUNC ;GET FUNCTION CAIN 2,2 ;READ TRNN 0,1B29+1B33+1B34+1B35 ; AND EITHER SILO P.E.,MEM P.E., DATA LATE ;OR DATA CHECK? JRST [SETOM DDERST ;NO, LET JOB 0 HANDLE IT SETOM DDERBP ;SAY WE HAVE NO DATA PAGES WITH THIS ERROR AOS JB0FLG ;AND GET JOB 0 IN TO LOOK AT IT JRST 0(3)] ;RETURN TO NORMAL DRMSV HRRZ 2,QPWB(1) ;SAVE ORIGINAL READ CORE PAGE ADDRESS MOVEM 2,DDERST ;AND TURN SCHED LEVEL ROUTINES ON WITH IT SETZM QPWA(1) SETZM DRMSTS(1) SOS CMDCNT JRST DRMEP2 ;AND CONTINUE DRUM ; THE FOLLOWING ROUTINES ARE DEVICE DEPENDENT ROUTINES CALLED FROM SCHED ; LEVEL THROUGH THE OPERATION TYPE (SWAPPER, UTILITY OP) DEPENDENT ; DISPATCH TABLES ; SWAPPER ROUTINES DISPATCH TABLE DRMSWD: JRST DRMEL2 ;REQUE COMMAND JRST UDRMSW ;TEST FOR SCHED LEVEL UDRMIO COMPLETION JRST DRMEL3 ;HANDLE PERMANENT ERROR JRST DRMEL4 ;HANDLE SUCCESSFULL COMPLETION ; UTILITY OP ROUTINES DISPATCH TABLE DRMUTD: JRST DRMEL8 ;REQUE COMMAND JRST UDRMSW ;TEST FOR SCHED LEVEL UDRMIO COMPLETION JRST DRMEL6 ;HANDLE PERMANENT ERROR JRST DRMEL5 ;HANDLE SUCCESSFULL COMPLETION ; REQUE SWAPPER DRUM READ AFTER BAD DATA HAS BEEN COPIED DRMEL2: MOVE 1,DDERST ;GET CORE ADDRESS LSH 1,-^D9 ;TURN INTO PAGE NUMBER HRRZ 1,CST1(1) ;GET DRUM ADDRESS DRMEL7: MOVEI 2,1000 ;READ A PAGE MOVE 3,DDERST ;INTO CORE ADDRESS JRST UDRMIO ;GO DO IT ; REQUE UTILITY DRUM READ AFTER BAD DATA HAS BEEN COPIED DRMEL8: LDB 1,[POINT 6,DRMEUT,26] ;GET COMMAND PAIR INDEX LSH 1,1 ;MAKE INTO COMMAND PAIR ADDRESS HLRZ 1,DRMCL-2(1) ;GET ORIGINAL DRUM ADDRESS TLZ 1,(1B0) ;TURN OFF NOT YET EXECUTED BIT JRST DRMEL7 ; HANDLE SWAPPER DRUM READ PERMANENT ERROR DRMEL3: MOVSI 3,SWPERR JRST .+2 ; HANDLE SWAPPER DRUM SUCCESSFULL READ DRMEL4: SETZ 3, ;SAY NO ERRORS MOVE 1,DDERST ;GET CORE ADDRESS LSH 1,-^D9 ;TURN INTO PAGE NUMBER IORM 3,CST3(1) ;INDICATE ANY POSSIBLE ERRORS JRST SWPDON ;GO TELL SWAPPER ; HANDLE UTILITY DRUM SUCCESSFULL READ DRMEL5: SETZ 1, ;SAY NO ERRORS ; HANDLE UTILITY DRUM READ PERMANENT ERROR DRMEL6: LDB 3,[POINT 6,DRMEUT,26] ;GET COMMAND PAIR INDEX LSH 3,1 ;TURN INTO ADDRESS MOVEM 1,DRMCL-2+1(3) ;STORE POSSIBLE ERRORS MOVSI 1,(1B0) ;TURN OFF EXECUTION AWAITING BIT ANDCAM 1,DRMCL-2(3) JRST (4) ;AND RETURN ; DRUM INITIALIZATION DRMIOI: SETOM DST ; MAKE ALL DST ENTRIES EMPTY MOVE 1, [XWD DST, DST+1] BLT 1, DST+NDST+1 DRMRST: SKIPG DRUMP ; DRUM ON-LINE RET ; NO MOVSI 1, -DRMSEC DRMII2: SETZM DRMRO(1) ; SET UP QUEUES SETZM DRMWO(1) SETZM DRMPO(1) SETZM DRMUO(1) MOVEI 2, DRMRO(1) MOVEM 2, DRMRI(1) MOVEI 2, DRMWO(1) MOVEM 2, DRMWI(1) MOVEI 2, DRMPO(1) MOVEM 2, DRMPI(1) MOVEI 2, DRMUO(1) MOVEM 2, DRMUI(1) IFN DRUM2,< SETZM DRMRO+DRMSEC(1) SETZM DRMWO+DRMSEC(1) SETZM DRMPO+DRMSEC(1) SETZM DRMUO+DRMSEC(1) MOVEI 2,DRMRO+DRMSEC(1) MOVEM 2,DRMRI+DRMSEC(1) MOVEI 2,DRMWO+DRMSEC(1) MOVEM 2,DRMWI+DRMSEC(1) MOVEI 2,DRMPO+DRMSEC(1) MOVEM 2,DRMPI+DRMSEC(1) MOVEI 2,DRMUO+DRMSEC(1) MOVEM 2,DRMUI+DRMSEC(1) > AOBJN 1, DRMII2 MOVSI 1,-NPWDS SETZM QPWA(1) SETZM QPWB(1) SETZM DRMSTS(1) AOBJN 1,.-3 SETOM DRMSEQ SETZM DRMFLG SETZM CMDCNT SETZM DRLOOP SETZM DRMINT SETZM DRMINT+1 MOVEI 1,DRMCL+2*NDRMCM-2 SETZM (1) MOVEM 1,-2(1) SUBI 1,2 CAILE 1,DRMCL JRST .-3 MOVEM 1,DRMFCL MOVEI 1,NDRMCM MOVEM 1,DRMCCT CONO DR0, DRMRES ; RESET DRUM MOVEI 1, ^D11000 SOJG 1, . ; WAIT AROUND 3OMS RET ;ASSIGN PAGE, EMPTIEST SECTOR ;"DRMASF" RETURNS CALLER+1 IF THE DRUM IS FULL OR UNAVAILABLE, ELSE ;CALLER+2 WITH THE DRUM ADDRESS ASSIGNED IN A. THE SECTOR CHOSEN FOR ;THE ASSIGNMENT HAS THE MOST FREE PAGES. "ASDRM" TRIES TO ASSIGN ;A PAGE AT SECTOR (A)+1 OR AS SOON AFTER AS POSSIBLE. IT RETURNS CALLER+1 ;IF NO FREE PAGES ARE LEFT OR CALLER+2 WITH THE DRUM ADDRESS IN A. INTERN DRMASN ASDRM: DRMASN: DRMASF: SKIPG DRMFRE ;ROOM AVAILABLE? JRST RETN ;NO, RETURN BAD MOVE 1,DRMLSA DRMAS1: CAIL 1,NDST/^D36+1 RET ;DRUM FULL SKIPE 3,DRMBIT(1) JFFO 3,SECFNR ;FOUND SOMETHING AOJA 1,DRMAS1 ;TRY AGAIN ;ASSIGN PAGE ON SWAPPING DISK DRMASD: SKIPG DRMFRE JRST RETN ;NO FREE PAGES MOVEI 1,NDST/^D36 DRMAD1: SKIPE 3,DRMBIT(1) JFFO 3,SECFND ;FOUND ONE SOJGE 1,DRMAD1 ;TRY AGAIN RET ;NONE FOUND SECFNR: MOVEM 1,DRMLSA SECFND: MOVE 3,BITS(4) ANDCAM 3,DRMBIT(1) ;REMOVE PAGE IMULI 1,^D36 ADDI 1,0(4) IDIVI 1,DRMSEC LSH 1,6 CAML 1,MAXDRM SOS DSKFRE IORI 1,0(2) TLO 1,1B34 ;SET DRUM BIT DRMSA1: SOS DRMFRE ;DECR. FREE PAGE COUNT DRMSA2: AOS 0(P) RETN: RET ;CONVERT DRUM ADDRESS INTO INDEX INTO DST INTERN GDSTX GDSTX: TLNN 2,14 ;INSIST ON REGULAR DRUM ADDRESS TLNN 2,2 BUG(HLT,) HRRZS 3,2 ;SPLIT BAND AND SECTOR ANDI 3,77 ;SECTOR LSH 2,-6 ;BAND IMULI 2,DRMSEC ADDI 2,0(3) CAIL 2,NDST BUG(HLT,) RET INTERN DASDRM DASDRM: CALL DEDRM JFCL BUG(HLT,) SETZM DNOGO ;RESET FLAG THAT PAGE IS AVAILABLE RET ;SET USED DRUM PAGE BITS AND CHECK BITS LS DRNSET,1 ;FLAG TO SAY PAGES ARE READ STBTWD: TLOA 2,(1B0) CHKDRR: TLZ 2,(1B0) ;SET FLAG LDB 3,[POINT 12,2,29] LDB 4,[POINT 6,2,35] IMULI 3,DRMSEC ADDI 3,0(4) IDIVI 3,^D36 MOVE 4,BITS(4) ;GET PROPER BIT JUMPL 2, [ TLZ 2,(1B0) ;SET BIT IN TABLE IORM 4,DRBTWD(3) RET ] TDNE 4,DRBTWD(3) ;TEST BIT AOS 0(P) RET ;ROUTINES TO ATTEMPT ASSIGNMENT OF A SPECIFIC DRUM ADDRESS ASDRMS: JSP 4,DRMBS TDNN D,DRMBIT(B) ;SKIP IF PAGE IS AVAILABLE RET ANDCAM D,DRMBIT(B) CAML 1,MAXDRM ;WAS IT A DSK PAGE OR A DRM PAGE SOS DSKFRE ;DISK PAGE JRST DRMSA1 ;ROUTINE TO RELEASE A DRUM PAGE DEDRM: JSP 4,DRMBS TDNE D,DRMBIT(B) ;CHECK IF NOT YET ASSIGNED RET ;SKIP RETURN IORM D,DRMBIT(B) CAMGE B,DRMLSA ;IS THIS IN FRONT OF FIRST FREE SECTOR MOVEM B,DRMLSA ;YES UPDATE POINTER CAML 1,MAXDRM AOS DSKFRE AOS DRMFRE AOS (P) RET ;MAKE DOUBLE SKIP RETURN ;CHECKS FOR LEGAL DRUM ADDRESS & GETS WORD & BIT INDICES TO BIT TABLE ;RETURNS BIT CHUNK WORD INDEX IN A, BIT TABLE WORD INDEX IN B, ;SECTOR NO. IN C, AND BIT POSITION MASK IN D DRMBS: ANDI A,-1 MOVE C,A ANDI C,77 CAIGE A,DRMBND*100 ;LEGAL BAND? CAIL C,DRMSEC ;LEGAL SECTOR? RET AOS (P) LDB 2,[POINT 12,1,29] LDB 3,[POINT 6,1,35] IMULI 2,DRMSEC ADDI 2,0(3) IDIVI 2,^D36 PUSH P,4 MOVE 4,BITS(3) LDB 3,[POINT 6,1,35] POPJ P,0 ;INITIALIZE DRUM BIT TABLES DRMINI: SETZM DRMBIT ;EACH "ONE" REPRESENTS A FREE PAGE MOVE A,[XWD DRMBIT,DRMBIT+1] BLT A,DRMBIT+ MOVSI F,-NDST SKIPG DRUMP ;SWAPPING TO DRUM ADD F,[XWD DSKNOV,DSKNOV] ;NO LEAVE SECTION FOR WHICH THEIR IS NO ; ;BACKUP FOR ON DISK ASSIGNED DRMIN3: HRRZI 1,0(F) IDIVI 1,DRMSEC CAIL 1,DRMBND JRST .+5 LSH 1,6 IORI 1,0(2) CALL DASDRM AOBJN F,DRMIN3 ;RELEASE ALL DRUM PAGES MOVEI A,DRMBND*DRMSEC ;NO. OF PAGES ON DRUM SKIPG DRUMP SUBI A,DSKNOV ;SUBTRACT NON OVERLAP PAGES IF NO DRUM MOVEM A,DRMFRE MOVE 2,MAXDRM LSH 2,-6 IMULI 2,DRMSEC SUB A,2 ;CALCULATE NUMBER OF PAGES OF SWAPPING DISK MOVEM 1,DSKFRE MOVE 1,[XWD DRBTWD,DRBTWD+1] SETZM DRBTWD BLT 1,DRBTWD+ MOVEI F,0 DRMIN1: MOVE A,DRMBBT(F) JUMPE A,DRMIN2 ;DONE ON 0 DRMIN5: PUSH P,A MOVEI 2,DRMSEC LSH A,6 DRMIN6: PUSH P,2 PUSH P,A CALL ASDRMS JFCL JFCL POP P,A ADDI A,1 POP P,2 SOJG 2,DRMIN6 POP P,A AOBJN A,DRMIN5 AOJA F, DRMIN1 DRMIN2: MOVEI F,0 DRMIN4: MOVE A,DRMBST(F) JUMPE A,DRMIOI ;DONE ON 0 DRMIN7: PUSH P,A CALL ASDRMS JRST [POP P,A ADDI A,100-DRMSEC JRST DRMIN7] JFCL POP P,A AOBJN A,DRMIN7 AOJA F,DRMIN4 DRMBBT: 0 ;BAD BAND TABLE ENTRIES ARE -N,,BBBBBB BLOCK 10 ;WHERE N IS NUMBER OF BANDS THAT ARE BAD ;AND BBBBBB IS A BAND ADDRESS. ;FOR EXAMPLE 200,,0 WOULD VARY FIRST DRUM OFFLINE DRMBST: 0 ;BAD SECTOR ENTRIES ARE -N,,BBBBSS BLOCK 6 ;WHERE N IS NUMBER OF SECTORS THAT ARE BAD ;AND BBBBSS IS DRUM ADDRESS BBBB BEING THE BAND ;AND SS BEING THE SECTOR. ;FOR EXAMPLE 200*^D13,,0 WOULD VARY FIRST DRUM OFFLINE MAXDRM: 40000 ;MAXIMUM DRUM ADDRESS END