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];