ER[EXAM]; % D I S K D I A G N O S T I C TO ASSEMBLE: @MI@ EXAM.MC LOAD: EXAM % * * * OUTGOING COMMAND BITS FROM MAXC TO DISK AND CONTROLLER * INSERT[DBEG.MC]; LVN[L20]; TARGET[ILC]; MP[UDSEL,13]; * DESELECT THE UNIT MP[RSC,7]; * RESET SECTOR CONDITION MP[RPDL,10]; * RESET PROCESSOR DATA LATE MP[RCDL,11]; * RESET CONTROLLER DATA LATE MP[RSO,12]; * RESET SECTOR OVERFLOW MP[I1EN,0]; * ENABLE SECTOR INTERRUPTS MP[I2EN,4]; * ENABLE TYPE 1 WORD INTERRUPTS MP[I3EN,5]; * ENABLE TYPE 2 WORD INTERRUPTS MP[I4EN,6]; * ENABLE TYPE 3 WORD INTERRUPTS MP[LCR,1]; * LOAD CYLINDER ADDRESS REGISTER MP[LHR,2]; * LOAD HEAD ADDRESS REGISTER MP[COM,3]; * INTERPRET THIS AS A COMMAND MP[WRGAT,20]; * TURN ON WRITING MP[RDGAT,21]; * TURN ON READING MP[ERGAT,24]; * TURN ON ERASING MP[SEEK,22]; * INITIATE SEEK TO C.A.R. MP[RHR,23]; * RESET HEAD ADDRESS REGISTER TO 0 MP[HDS,25]; * ACTIVATE R/W HEAD IN H.A.R. MP[RESTOR,26]; * SEEK TO CYLINDER 0 SP[RESET,RSC,RPDL,RCDL,RSO]; * RESETS CONTROLLER ERRORS PM[ALL1CYL,777 0000]; F[HDADR,23,27]; * HEAD ADDRESS FIELD F[CYLADR,17,27];* CYLINDER ADDRESS FIELD * * INCOMING STATUS FROM DISK AND CONTROLLER * MP[IC,0]; * INDEX CONDITION MP[UUNS,1]; * UNIT UNSAFE MP[UOFF,2]; * UNIT OFF LINE MP[UNR,3]; * UNIT NOT READY (NORMALLY = SEEKING) MP[SKFAIL,4]; * SEEK HAS FAILED MP[URDONLY,5]; * UNIT CANNOT BE WRITTEN ON MP[CNR,6]; * CONTROLLER IS NOT READY MP[SC,7]; * SECTOR CONDITION MP[PDL,10]; * PROCESSOR DATA LATE CONDITION MP[CDL,11]; * CONTROLLER DATA LATE CONDITION MP[SO,12]; * SECTOR OVERFLOW CONDITION * * SELECT THE PROPER DISK UNIT * MC[UNIT]; MC[DISCONN,UDSEL,RESET]; MC[RESTORC,I1EN,RESET,COM,RESTOR]; MC[IDLE,I1EN,RESET]; MC[CURSEC]; MC[ISTAT]; SELUNIT:Q←7S; SU1: KUNIT←Q; P←AQ; KSET←DISCONN,KNEWCOMM; P←P-1; Q←P,GOTO[SU1,ALU>=0]; Q←3S; CURSEC←Q; KUNIT←UNIT; P←P; KSET←IDLE,KNEWCOMM; CALL[WAITRDY]; KSET←RESTORC,KNEWCOMM; CALL[WAITRDY]; KSET←IDLE,KNEWCOMM; ARM←2160S; RETURN; * * WAIT UNTIL DISK UNIT AND CONTROLLER BOTH READY * MC[ALLRDY,UOFF,SKFAIL,UNR,CNR]; WAITRDY:Q←ALLRDY; P←KSTAT; P←P AND Q; GOTO[.-2,ALU#0]; RETURN; * * INTERRUPT HANDLERS FOR SECTOR AND WORD INTERRUPTS * IM[SILOC,5]; SILOC[(YKPTR←KUNIT,CALL[SIHAND])]; IM[WILOC,11]; REPEAT[3,WILOC[(YKPTR←KUNIT,CALL[WIHAND])]]; MC[SECRDY]; MC[WDRDY]; MC[RSCC,RSC,I1EN]; MC[KDO]; MC[KDOL]; MC[KDI]; MC[KDIL]; MC[SIUNIT]; MC[WIUNIT]; MC[QAFT]; MC[WDWRTN]; MC[WDWRTNL]; MC[I2ENWD,I1EN,I2EN]; MC[OOPSMSK,BADUNIT,PDL,CDL,SO]; SIHAND: QAFT←Q; P←UNIT; Q←KUNIT; P-Q, KCSET←RSCC; Q←1S, GOTO[SIEX,ALU#0]; SECRDY←Q; Q←OOPSMSK; P←KSTAT; P←P AND Q; CALL[ANALYZE,ALU#0]; SIUNIT←Y; P←CURSEC; Q←P+1, P←3S; P-Q, P←KSTAT; CURSEC←Q, PQ RCY [43], GOTO[ZEROSEC,ALU=0]; Q←P; GOTO[SIEX,QEVEN]; Q←2S; CURSEC←Q,GOTO[SIEX]; ZEROSEC:CURSEC←NULL; SIEX: Q←QAFT, RETURN, P←P1, IRET; WIHAND: P←AQ, Q←WDRDY; Q←1S, P←P, GOTO[.+2,QEVEN]; DATLAT: BRKP[1]; WDRDY←Q; WIUNIT←Y; KMDR←KDO; KMDRL←KDOL; Q←KWDATA; Q←KRDATA; KDI←Q; KDIL←KMDRL, Q←P; KCSET←I2ENWD; RETURN, P←P1, IRET; * * WAIT FOR THE BEGINNING OF THE SELECTED SECTOR * MC[SECTOR]; WAITSEC:SECRDY←NULL; KUNIT←7S; WIX1: P←SECRDY; P; GOTO[WIX1,ALU=0]; SECRDY←NULL; Q←CURSEC; P←SECTOR; P-Q; GOTO[WIX1,ALU#0]; KUNIT←UNIT,RETURN; * * WAIT UNTIL READY FOR NEXT WORD. INTERRUPT 4 REQUEST MUST NOT * BE BACK-PANEL JUMPERED. * SP[BADUNIT,UUNS,UOFF,UNR,SKFAIL,URDONLY]; MC[WDW]; MC[WDSCOPE]; WAITWD: P←WDRDY; P; GOTO[WW0,ALU=0]; DATLAT1:BRKP[1],GOTO[WW0]; WW0: Q←OOPSMSK,INHINT; P←KSTAT,INHINT; P AND Q; CALL[ANALYZE,ALU#0]; P←WDRDY; P; P←NULL, GOTO[WW0,ALU=0]; WDRDY←NULL,RETURN; * * ANALYZE WHY WAITWD FAILED * SV[CONDMSK,7777 7777 7777]; ANALYZE:Q←P AND Q, P←CONDMSK; P AND Q; GOTO[.+2,ALU=0]; STOP1: BRKP[1], GOTO[PURIFY]; AQ, RETURN; * SET THE ALU OUTPUT NONZERO, REQUESTING RECOVERY * PURIFY: IRET; P←P; KUNIT←UNIT; P←P; KSET←IDLE, KNEWCOMM; Q←3S; CURSEC←Q, GOTO[XFLP]; * * SEEK TO CYLINDER SPECIFIED IN CURCYL[17-27]. * MC[CURCYL,UZERO]; MC[CYLCOM,UZERO]; MC[SCRCOM,LCR,RESET,I1EN]; MC[SEECOM,COM,RESET,SEEK,I1EN]; SEEKSUB:CALL[WAITRDY]; Q←CURCYL; P←SCRCOM; Q← P OR Q; CYLCOM←Q; KSET←CYLCOM,KNEWCOMM; CALL[WAITRDY]; KSET←SEECOM,KNEWCOMM; CALL[WAITRDY]; RETURN; * * SET HEAD REGISTER * MC[RESETHD,RESET,COM,RHR,I1EN]; MC[SETHD,LHR,I1EN]; MC[SHCOM]; MC[HEAD]; SETHDSUB:KSET←RESETHD,KNEWCOMM,CALL[WAITRDY]; P←HEAD; Q←SETHD; Q←P OR Q; SHCOM←Q; KSET←SHCOM,KNEWCOMM,CALL[WAITRDY]; RETURN; * * ROUTINE TO SET UP PARAMETERS FOR BLOCKS OF WORDS TO BE * TRANSFERRED. DRIVEN BY A TABLE WITH THREE WORDS PER ENTRY. * FIRST, A CODE FOR THE ROUTINE TO BE USED. SECOND, A STARTING * ADDRESS IN A MEMORY. THIRD, THE LENGTH OF THE BLOCK. * MC[ROUTINE]; MC[WDSTOXF]; MC[MEMAD]; MC[WDTPTR]; SV[WCONS,1234567]; MC[RCONS]; MC[CKSUM2]; * MC[DHDWD]; MC[DUNBLK]; MC[DUB1]; MC[DUB2]; MC[DUB3]; MC[PREDAT]; MC[PD1]; * SV[WDTB1,0]; SV[WDTB1A,IP[DHDWD]]; SV[WDTB1B,1]; SV[WDTB2,1]; SV[WDTB2A,0]; SV[WDTB2B,1]; SV[WDTB3,0]; SV[WDTB3A,IP[DUNBLK]]; SV[WDTB3B,4]; SV[WDTB4,1]; SV[WDTB4A,0]; SV[WDTB4B,1]; SV[WDTB5,0]; SV[WDTB5A,IP[PREDAT]]; SV[WDTB5B,2]; SV[WDTB6,2]; SV[MMAD,0]; SV[WDTB6B,1000]; SV[WDTB7,1]; SV[WDTB7A,0]; SV[WDTB7B,1]; * SV[@WDTAB,IP[WDTB1]]; TESTAD: P←WDW; Q←P+1,P←WDSTOXF; WDW←Q; TAD0: Q←P-1; WDSTOXF←Q,RETURN[ALU>=0]; Y←WDTPTR; Q←SY,INCY; ROUTINE←Q; Q←SY,INCY; MEMAD←Q; P←SY,INCY; WDTPTR←Y,GOTO[TAD0]; * * GET A WORD FOR THE DISK. * MC[CKSUM]; FETIT: CALL[TESTAD]; P←ROUTINE; P←P; P←P-1,GOTO[SMF,ALU<=0]; P←P-1,GOTO[CKSUMF,ALU<=0]; P←P-1,GOTO[MMF,ALU<=0]; P←P-1,GOTO[CONSF,ALU<=0]; ADF: P←Q←MEMAD; Q←P+1,KDO←Q; MEMAD←Q; P←KDO; Q←17S; Q←P AND Q; KDOL←Q,GOTO[MMF1]; CONSF: Q←WCONS; KDO←Q; KDOL←NULL,GOTO[MMF1]; MMF: P←KREAD←MEMAD,CALL[ONEINST]; KDO←KMDR; Q←P+1,KDOL←KMDRL; MEMAD←Q; MMF1: P←Q←CKSUM; P←PQ RCY [1],Q←KDO; P←P+Q,Q←KDOL; Q←P+Q; CKSUM←Q,RETURN; SMF: Y←MEMAD; Q←SY,INCY; KDO←Q; P←DHDWD; P-Q; GOTO[.+2,ALU=0]; NOTHD: P←NULL; KDOL←NULL; MEMAD←Y,GOTO[MMF1]; CKSUMF: Q←CKSUM; KDO←Q; CKSUM2←Q; Q←1S; KDOL←Q; CKSMOK: CKSUM←NULL; TWOINST:P←P; ONEINST:RETURN; * * DISPOSE OF A WORD FROM THE DISK. * STORIT: CALL[TESTAD]; P←ROUTINE; P←P; P←P-1,GOTO[SMS,ALU<=0]; P←P-1,GOTO[CKSUMS,ALU<=0]; P←P-1,GOTO[MMS,ALU<=0]; P←P-1,GOTO[CONSS,ALU<=0]; ADS: P←Q←MEMAD; P←P+1; Q←P,P←MEMAD; MEMAD←Q; Q←KDI; P#Q; GOTO[DATERR,ALU#0]; Q←KDIL; Q←P#Q,P←17S; P AND Q; GOTO[MMS1,ALU=0]; GOTO[DATERR]; CONSS: Q←KDI; P←WCONS; P#Q; RCONS←Q,GOTO[MMS1,ALU=0]; DATERR: BRKP[1],GOTO[MMS1]; MMS: KMDR←KDI; KMDRL←KDIL; P←KWRITE←MEMAD; Q←P+1; MEMAD←Q; MMS1: P←Q←CKSUM; P←PQ RCY [1],Q←KDI; P←P+Q,Q←KDIL; Q←P+Q; CKSUM←Q,RETURN; SMS: Y←MEMAD; Q←KDI; SY←Q,INCY; MEMAD←Y,GOTO[MMS1]; CKSUMS: P←KDI; Q←CKSUM; P-Q; GOTO[CKSMOK,ALU=0]; CKSMERR:P←KSTAT; BRKP[1],GOTO[CKSMOK]; * * AFTER PAUSING FOR PAUS WORDS, READ A RECORD OF LREC WORDS, LEAVING * ITS LAST WORD IN KDI AND KDIL. * MC[LREC]; MC[PAUS]; MC[WDSPAUSD]; MC[WDSREAD]; MC[HDSEL,COM,HDS,I1EN]; MC[HDSELWI,COM,HDS,I1EN,I4EN]; MC[READC,COM,RDGAT,HDS,I4EN,I1EN]; READREC:WDSPAUSD←NULL; WDRDY←NULL; KSET←HDSELWI; CALL[WW0]; RR1: P←WDSPAUSD; Q←PAUS; P-Q; Q←P+1,GOTO[RR2,ALU>=0]; WDSPAUSD←Q,CALL[WAITWD]; GOTO[RR1]; RR2: WDSREAD←NULL; KSET←READC; * GIVE READ COMMAND P←NULL; * LET ANY PENDING INTERRUPT HAPPEN P←NULL; P←NULL; P←NULL; WDRDY←NULL,CALL[WAITWD]; * CLEAR WORD READY FLAG AND WAIT RDLP: P←WDSREAD; Q←LREC; P-Q; Q←P+1,GOTO[TURNOFF,ALU>=0]; WDSREAD←Q,CALL[WAITWD]; CALL[STORIT]; GOTO[RDLP]; * * WRITE A RECORD OF PAUS ZERO WORDS, ONE SYNC WORD, LREC DATA WORDS, * AND BETWEEN ONE AND TWO GARBAGE WORDS. * MC[WDSWRT]; SV[SYNC,17]; MC[WRITC,COM,WRGAT,ERGAT,HDS,I4EN,I1EN]; MC[ERASC,COM,ERGAT,HDS,I4EN,I1EN]; WRTREC: WDSPAUSD←NULL; KDO←NULL; KDOL←NULL; WDRDY←NULL; KSET←WRITC; CALL[WW0]; WR1: P←WDSPAUSD; Q←PAUS; P-Q; Q←P+1,GOTO[WR2,ALU>=0]; WDSPAUSD←Q,CALL[WAITWD]; GOTO[WR1]; WR2: WDSWRT←NULL; Q←SYNC; KDO←Q; KDOL←Q,CALL[WAITWD]; WRTLP: P←WDSWRT; Q←LREC; P-Q; Q←P+1,GOTO[WR3,ALU>=0]; WDSWRT←Q; CALL[FETIT]; CALL[WAITWD]; GOTO[WRTLP]; WR3: KDO←NULL; KDOL←NULL,CALL[WAITWD]; CALL[WAITWD]; CALL[WAITWD]; CALL[WAITWD]; KSET←ERASC,CALL[WAITWD]; CALL[WAITWD]; CALL[WAITWD]; TURNOFF:KSET←HDSEL; RETURN; * * ISSUE COMMANDS CONTINUOUSLY TO THE DISK * COMCONT:CALL[SETUP],INHINT; CC1: KSET←HDSEL; GOTO[CC1]; * * SET UP THE PROCESSOR TO TAKE INTERRUPTS ON DISK CHANNELS 1 AND 4, * PROCESSOR CHANNELS ???. THEN SELECT THE UNIT. * SETUP: ARM←0S,INHINT; SETF[100S],INHINT; IRET,INHINT; P←NULL,INHINT; CALL[SELUNIT]; RETURN; * * UNPACK THE HEAD, CYLINDER, AND SECTOR FROM THE DSKADR WORD. * MC[DSKADR]; UNPK: CALL[CKDSKAD]; Q←DSKADR; P←77 0000S; Q←P AND Q; HEAD←Q; Q←DSKADR; P←7770S; P←Q←P AND Q; P←PQ RCY [33]; Q←P; CURCYL←Q; Q←DSKADR; P←7S; Q←P AND Q; SECTOR←Q; RETURN; * * READ THROUGH A SECTOR UNTIL REACHING WORD WDNO. THE RECORD FORMAT * OF THE SECTOR IS DETERMINED BY A TABLE FMTAB WITH TWO WORDS PER RECORD. * THE FIRST WORD GIVES THE NUMBER OF WORDS TO PAUSE BEFORE TRYING TO * READ THE RECORD. THE SECOND WORD GIVES THE LENGTH OF THE RECORD. * SV[WDNO,0]; SV[FULLSEC,1012]; MC[WDSDONE]; SV[FMTAB1,5]; SV[FMTAB1A,2]; SV[FMTAB2,3]; SV[FMTAB2A,5]; SV[FMTAB3,3]; SV[FMTAB3A,1003]; SV[FMTAB4,0]; *FOR FUTURE EXPANSION SV[FMTAB4A,0]; SV[@FMTAB,IP[FMTAB1]]; MC[HDSEL1,RESET,COM,HDS,I1EN]; MC[FMTPTR]; SV[PAUSDELT,3]; SV[NREADRECS,3]; MC[NRRNOW]; MC[LSTAT]; XFSEC: CALL[UNPK]; CALL[SEEKSUB]; CALL[SETHDSUB]; CALL[WAITSEC]; XF0: KSET←HDSEL1,KNEWCOMM; WDSDONE←NULL; Q←@FMTAB; FMTPTR←Q; WDSTOXF←NULL; Q←@WDTAB; WDTPTR←Q; CKSUM←NULL; NRRNOW←NULL; WDW←NULL; XF1: Y←FMTPTR; Q←SY,INCY; PAUS←Q; P←WDNO; Q←WDSDONE; P←P-Q; GOTO[QUIT,ALU<=0]; Q←SY,INCY; P-Q; GOTO[.+2,ALU>=0]; Q←P; LREC←Q; P←WDSDONE; Q←P+Q; WDSDONE←Q; FMTPTR←Y; P←NRRNOW; Q←P+1,P←NREADRECS; P-Q,NRRNOW←Q; GOTO[RDIT,ALU>=0]; Q←PAUS; P←PAUSDELT; Q←P+Q; PAUS←Q,CALL[WRTREC]; GOTO[XF1]; RDIT: CALL[READREC]; GOTO[XF1]; QUIT: KSET←IDLE,KNEWCOMM; RETURN; * * INCREMENT DISK ADDRESS AND CHECK FOR VALIDITY. * SV[DAD1,1]; SV[DAD1A,7]; SV[DAD1B,2]; SV[DAD1C,7777 7777 7770]; SV[DAD2,1 0000]; SV[DAD2A,77 0000]; SV[DAD2B,23 0000]; SV[DAD2C,7777 7700 7777]; SV[DAD3,10]; SV[DAD3A,7770] SV[DAD3B,6250]; SV[DAD3C,7777 7777 0007]; SV[@DAD,IP[DAD1]]; MC[CARRY]; NXTDSKAD:Y←@DAD; X←2S; Q←1S; CARRY←Q; NADLP: P←SY,INCY; Q←CARRY; AQ; Q←DSKADR,GOTO[.+2,ALU<=0]; Q←P+Q; DSKADR←Q; P←SY,INCY; Q←P AND Q; P←SY,INCY; P-Q; DECX,GOTO[INBNDS,ALU>=0]; Q←CARRY; AQ; GOTO[BADADR,ALU<=0]; P←DSKADR; Q←SY,INCY; Q←P AND Q; DSKADR←Q,GOTO[NADLP,X>=0]; INBNDS: CARRY←NULL,INCY,GOTO[NADLP,X>=0]; RETURN; BADADR: GOTO[.],BRKP[1]; * CKDSKAD:Y←@DAD; X←2S; CARRY←NULL; GOTO[NADLP]; * * STORE THE RANDOM NUMBER GENERATOR PARAMETERS IN MAIN MEMORY * LOCATIONS RNM1 AND DOWNWARD. * SV[RNM0,0]; SV[RNM1,20]; SV[RNM2,777]; MC[CMAD]; RNS: Q←RNM1; CMAD←Q; X←20S; RNSLP: RETURN[X<0]; Q←LX; MDR←Q; P←WRITE←CMAD; Q←P-1; CMAD←Q,DECX,GOTO[RNSLP]; * * LOAD THE RANDOM NUMBER GENERATOR PARAMETERS FROM MAIN * MEMORY LOCATIONS RNM1 AND DOWNWARD. * RNL: Q←RNM1; CMAD←Q; X←20S; RNLLP: RETURN[X<0]; P←READ←CMAD; Q←P-1; CMAD←Q; P←MDR; LX←P,DECX,GOTO[RNLLP]; * * GENERATE THE NEXT RANDOM NUMBER; LEAVE IT IN Q. ASSUMES L * REGISTERS AND X ARE LEFT FROM LAST CALL. * NXTRN: Q←L20,GOTO[.+2,X>=0]; X←17S; P←LX; LX←Q←P+Q,DECX; L20←AQ,RETURN; * * STORE RANDOM NUMBER GENERATOR PARAMETERS IN MAIN MEMORY AND THEN * FROM THOSE PARAMETERS GENERATE RANDOM WORDS INTO MAIN MEMORY WORDS * RNM1+1 THROUGH RNM2. * SRPG: CALL[RNS]; X←NULL; P←RNM1; SRPGL: Q←P+1,P←RNM2; P-Q,CMAD←Q; RETURN[ALU<0]; CALL[NXTRN]; MDR←Q,CALL[NXTRN]; MDRL←Q; P←WRITE←CMAD,GOTO[SRPGL]; * * READ RANDOM NUMBER GENERATOR PARAMETERS FROM MAIN MEMORY AND THEN * CHECK THE MAIN MEMORY WORDS IN RNM1+1 TO RNM2 BY COMPARING THEM * WITH OUTPUT FROM THE RANDOM NUMBER GENERATOR. * SV[ERRCNT,0]; CRPG: X←20S; * SAVE GENERATION PARAMETERS P←LX; RX←P,DECX; GOTO[.-2,X>=0]; CALL[RNL]; X←NULL; P←RNM1; CRPGL: Q←P+1,P←RNM2; P-Q,CMAD←Q; GOTO[RPRESTOR,ALU<0]; READ←CMAD,CALL[NXTRN]; P←MDR; P#Q; CALL[RDATERR,ALU#0]; CALL[NXTRN]; P←MDRL; Q←P#Q,P←17S; P AND Q; CALL[RDATERR,ALU#0]; P←CMAD,GOTO[CRPGL]; * RDATERR:P←ERRCNT,BRKP[1]; Q←P+1; ERRCNT←Q; POP; POP; GOTO[DOSEC]; * RPRESTOR:X←20S; * RESTORE GENERATION PARAMETERS P←RX; LX←P,DECX; GOTO[.-2,X>=0]; RETURN; * * DUMP OR CHECK NSEC SECTORS OF RANDOM INFORMATION STARTING AT * DISK ADDRESS DSTRTAD. * SV[NSEC,57450]; SV[DSTRTAD,7775 0000 0000]; MC[SECLFT]; MC[PDSKADR]; SV[DISTAB,2]; SV[DISTAB1,0]; SV[DISTAB2,7777 7777 7776]; SV[@DISTAB,IP[DISTAB]]; MC[RANAD]; RSTR: CALL[SETUP],INHINT; RANAD←NULL; Q←3S,GOTO[DMPRCOM]; * DMPR: CALL[SETUP],INHINT; RANAD←NULL; Q←1S; L20←AQ,GOTO[DMPRCOM]; * RSTRR: CALL[SETUP],INHINT; Q←1S; RANAD←Q; Q←3S,GOTO[DMPRCOM]; * DMPRCOM:NREADRECS←Q; Q←DSTRTAD; DSKADR←Q; Q←FULLSEC; WDNO←Q; P←NSEC; Q←P-1; SECLFT←Q; Q←RNM0; MMAD←Q; DMPRLP: Q←DSKADR; * PERMUTE THE SECTORS ON A TRACK FOR FASTER PDSKADR←Q; * ACCESS P←3S; Q←P AND Q,P←@DISTAB; Q←P+Q,P←DSKADR; Y←Q; Q←SY; Q←P+Q; DSKADR←Q; CALL[SRPG]; DOSEC: CALL[XFSEC]; CALL[CRPG]; Q←DHDWD; P←DSKADR; P-Q; GOTO[.+2,ALU=0]; HDRERR2:BRKP[1],GOTO[.]; Q←PDSKADR; DSKADR←Q; P←SECLFT; Q←P-1; SECLFT←Q,RETURN[ALU<0]; P←RANAD; P; GOTO[.+3,ALU=0]; CALL[GRANAD]; GOTO[DMPRLP]; CALL[NXTDSKAD]; GOTO[DMPRLP]; * * GENERATE A RANDOM DISK ADDRESS. * MC[MASK]; MC[LIM]; MC[LPCT]; GRANAD: Y←@DAD; Q←2S; LPCT←Q; GRANADLP:INCY; Q←SY,INCY; MASK←Q; Q←SY,INCY; LIM←Q; GENIT: CALL[NXTRN]; P←MASK; Q←P AND Q,P←LIM; P-Q; GOTO[GENIT,ALU<0]; LIM←Q; P←DSKADR; Q←SY,INCY; P←P AND Q,Q←LIM; Q←P OR Q; DSKADR←Q; P←LPCT; Q←P-1; LPCT←Q,GOTO[GRANADLP,ALU>=0]; RETURN; * * DUMP MAIN MEMORY ON THE DISK. * SV[STRTLOC,0]; SV[ENDLOC,37 7777]; DMPM: CALL[SETUP],INHINT; Q←1S; NREADRECS←Q; GOTO[DRMEM]; * RSTM: CALL[SETUP],INHINT; Q←3S; NREADRECS←Q; GOTO[DRMEM]; * DRMEM: Q←DSTRTAD; DSKADR←Q; Q←FULLSEC; WDNO←Q; Q←STRTLOC; MMAD←Q; RSTLP: P←MMAD; Q←ENDLOC; P-Q; GOTO[.+2,ALU<=0]; RETURN; Q←DSKADR; DHDWD←Q; CALL[XFSEC]; P←DHDWD; Q←DSKADR; P-Q; GOTO[.+2,ALU=0]; HDRERR: BRKP[1],GOTO[DRMEM]; CALL[NXTDSKAD]; P←MMAD; Q←1000S; Q←P+Q; MMAD←Q,GOTO[RSTLP]; * * WRITE ADDRESSES ON A PACK * SV[PKNO,7775 0000 0000]; MC[SECSLFT]; PKINIT: CALL[SETUP],INHINT; NREADRECS←NULL; PKCOM: Q←2S; WDNO←Q; Q←7777 7700 0000S; P←PKNO; Q←P AND Q; DSKADR←Q; Q←57450S; * NUMBER OF SECTORS PER PACK SECSLFT←Q; PKLP: P←SECSLFT; Q←P-1; SECSLFT←Q,GOTO[PKEXIT,ALU<0]; Q←DSKADR; DHDWD←Q; CALL[XFSEC]; P←DHDWD; Q←DSKADR; P-Q; GOTO[HDRERR,ALU#0]; Q←DSKADR; P←PKNO; P←P#Q,Q←7777 7700 0000S; P←P AND Q; GOTO[CKR,ALU=0]; PKNOERR:BRKP[1],GOTO[.]; CKR: CALL[NXTDSKAD]; GOTO[PKLP]; PKEXIT: RETURN,BRKP[1]; * PKCK: CALL[SETUP],INHINT; Q←1S; NREADRECS←Q,GOTO[PKCOM]; * CKRST: CALL[SETUP],INHINT; GOTO[CKR]; * * TRANSFER A SECTOR REPEATEDLY * XFRPT: CALL[SETUP],INHINT; XFLP: CALL[CKDSKAD]; CALL[UNPK]; CALL[SEEKSUB]; CALL[SETHDSUB]; CALL[WAITSEC]; CALL[XF0]; GOTO[XFLP]; * * WRITE ADDRESSES IN MAIN MEMORY * MC[CURLOC]; SV[@CURLOC,IP[CURLOC]]; WMMAD: Y←@CURLOC,CALL[SETUP],INHINT; WMM1: Q←STRTLOC; CURLOC←Q; WMMLP: Q←CURLOC; P←ENDLOC; P-Q; GOTO[.+2,ALU>=0]; ****THIS CODE PROBABLY NEEDS MODIFICATION**** WMDONE: BRKP[1],GOTO[.]; Q←MDR←SY; P←MDR, CALL[PQCOMP]; Q←MDRL←SY; P←AQ,Q←17S; Q←P AND Q; P←MDRL,CALL[PQCOMP]; P←WRITE←CURLOC; P←P; P←P; * MAKE THIS LOOP MORE THAN TWO MREFS LONG P←P; P←P; P←P; P←P; P←P; Q←P+1; CURLOC←Q,GOTO[WMMLP]; * * SET THE MAIN MEMORY TO ZEROS * SV[ZERO,0]; SV[@ZERO,IP[ZERO]]; ZMEM: Y←@ZERO,CALL[SETUP],INHINT; GOTO[WMM1]; * * CHECK FOR CORRECT MEMORY CONTENTS * CKMMAD: Q←STRTLOC,CALL[SETUP],INHINT; CURLOC←Q; CKMLP: Q←CURLOC; P←ENDLOC; P-Q; GOTO[.+2,ALU>=0]; CKMDONE:BRKP[1],GOTO[.]; READ←CURLOC; P←CURLOC; Q←MDR; P#Q; GOTO[.+2,ALU=0]; CONBAD: BRKP[1],GOTO[.]; Q←17S; P←P AND Q; Q←MDRL; P#Q; GOTO[CONBAD,ALU#0]; P←CURLOC; Q←P+1; CURLOC←Q,GOTO[CKMLP]; * * CALL THE MEMORY DUMP AND RESTORE ROUTINES * DMPMEM: CALL[DMPM],INHINT; BRKP[1],GOTO[.-1]; * RSTMEM: CALL[RSTM],INHINT; BRKP[1],GOTO[.-1]; * DMPRAN: CALL[DMPR],INHINT; GOTO[.-1],BRKP[1]; * RSTRAN: CALL[RSTR],INHINT; GOTO[.-1],BRKP[1]; * RSTRRAN:CALL[RSTRR],INHINT; BRKP[1],GOTO[.-1];