TITLE KISER - KI10 PROCESSOR DEPENDENT CODE - V375 SUBTTL J.M. FLEMMING/JMF/DAL TS 10 SEP 85 SEARCH F,S $RELOC $HIGH ;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; .CPYRT<1973,1986> ;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986 ;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS. ;ALL RIGHTS RESERVED. ; ; ;DATE LOAD EDIT ; ; ; XP VKISER,375 ; PUT VERSION NUMBER IN GLOB LISTING AND LOADER STORAGE MAP ENTRY KISER ;LOAD KISER IF LIBRARY SEARCH KISER:: SUBTTL CLOCK1 - INTERFACE TO JOB STARTUP, STOP, AND CONTEXT SWITCHING ROUTINES SUBTTL TRAP HANDLING AND CONTEXT SWITCHING ;HERE TO PROCESS USER ARITHMETIC OVERFLOW TRAPS SAROVF::MOVE T1,.UPMP+.UPMUP ;GET PC MOVE T3,.JDAT+JOBENB## ;GET USER'S ENABLE BITS TRNN T3,AP.AOV ;OVERFLOW - IS THE USER ENABLED? TLNE T1,(XC.FOV) ;TRAP CAUSED BY FOV? CAIA ;YES, JRST SAROV6 ;NOT ENABLED, IGNORE IT HRRI T3,AP.AOV+AP.FOV;ASSUME FLOATING OVERFLOW TLNN T1,(XC.FOV) ;WAS IT A FLOATING OVERFLOW TRAP? TRZ T3,AP.FOV ;NO, INTEGER OVERFLOW ;HERE WITH T1=PC, T3=APRENB BITS SAROV3: TLZ T1,637 ;CLEAR BITS FOR COMPATABILITY MOVEM T1,.JDAT+JOBTPC## ;SAVE OLD PC MOVEM T3,.JDAT+JOBCNI## ;LIKE CONI ON THE KA-10 MOVE T3,.JDAT+JOBENB## ;GET USER'S ENABLE BITS TRNE T3,XP.DDU ;USER WANT TRAPS REENABLED? JRST SAROV5 ;YES, LEAVE AS IS HLLZS .JDAT+JOBENB## ;CLEAR USER'S ENABLE BITS SO MUST DO APRENB AGAIN MOVEI T3,UP.PFT MOVEM T3,.UPMP+.UPPFT ;EXEC WILL FIELD ILM MOVSI T3,(JFCL) ;NOP MOVEM T3,.UPMP+.UPAOT ;IGNORE ARITHMETIC TRAPS MOVEI T3,UP.PDT MOVEM T3,.UPMP+.UPPDT ;EXEC WILL FIELD PDL OVERFLOWS SETZM .CPCN1## ;CLEAR POSSIBLE NXM OR CLOCK ENABLES SAROV5: MOVEI T3,XP.CLK ;ALWAYS DISABLE CLOCK ANDCAM T3,.CPCN1## HRRZ T3,.JDAT+JOBAPR## ;PC IN TRAP ROUTINE? CAIE T3,0(T1) CAIN T3,-1(T1) JRST SAROV7 ;YES HRR T1,.JDAT+JOBAPR## ;GET USER'S TRAP ADDRESS TLZ T1,(XC.OVF+XC.FOV+XC.FUF+XC.NDV+IC.BIS+IC.AFI) TLO T1,(XC.PUB!XC.USR) ;INSURE PUBLIC AND USER MODE IS SET SAROV6: MOVEM T1,.UPMP+.UPMUO ;NEW PC WITH TRAP CAUSING BITS CLEARED MOVE P,[XWD MJOBPD##,.JDAT+JOBPDL##] ;SET UP A STACK PUSHJ P,SCDCHK## ;CHECK IF WE SHOULD RESCHEDULE JEN @.UPMP+.UPMUO ;EXIT TO THE USER'S TRAP HANDLER SAROV7: HLLZM T1,.CPAPC## ;SAVE OLD PC FOR THE ERROR MESSAGE HRRZM T1,.CPAPC##+1 MOVEI T1,XP.LTH ;STUCK IN LOOP BIT HRRM T1,.CPAEF## JRST SEPDL3 SEPDLO::EXCH T1,.UPMP+.UPMUP ;GET THE PC HLLZM T1,.CPAPC## ;SET AS ERROR PC FOR ERRCON HRRZM T1,.CPAPC##+1 ; .. HRRI T1,AP.POV ;SET PUSH DOWN OVERFLOW FLAG SEPDL1: HRRM T1,.CPAEF## ;IN .CPAEF SO ERRCON WILL GET CALLED MOVE T1,.UPMP+.UPMUP ;RESTORE T1 SEPDL3: SETOM .CPSCF## ;SET FORCED RESCHEDULING FLAG SETOM .CPCKF## ;AND CLOCK FLAG CONO PI,CLKBIT##+PI.IIO ;REQUEST A CLOCK INTERRUPT AND TURN THE PI SYSTEM ON CONSO PI,II.IPA ;ANY PIS IN PROGRESS? JRST . ;WAIT UNTIL CLOCK LEVEL HAPPENS AND THE JOB ; IS STOPPED IF IN USER MODE. IF THE PC IS IN ;EXEC MODE, ERRCON WILL CONTINUE AT ; (.CPAPC) INSTEAD OF HERE MOVEM P,PIPPDL ;SAVE OLD STACK POINTER MOVEI P,PIPPDL ;AND GET NEW ONE STOPCD .,STOP,PIP, ;++PI IN PROGRESS $LOW PIPPDL: EXP 0 BLOCK 1 $HIGH SEILM:: SKIPN .CPEJ1## ;ALREADY BEEN HERE (T1 AND T2 SAVED)? DMOVEM T1,.CPST1## ;NO, SAVE T1 AND T2 HERE MOVE T1,.UPMP+.UPMUP ;GET THE PC HLLZM T1,.CPAPC## ;STORE IT AS POTENTIAL ERROR PC HRRZM T1,.CPAPC##+1 ; .. MOVE T2,.UPMP+.UPUPF ;GET THE USER PAGE FAIL WORD TLNN T1,(XC.USR) ;DID THE PAGE FAULT OCCUR IN USER MODE? SKIPA T2,.UPMP+.UPEPF ;NO, GET THE EXEC PAGE FAIL WORD MOVE T3,T2 ;USER PAGE FAULT, SAVE PC FOR POSSIBLE CALL TO USRFLT MOVEM T2,.CPPFW## ;STORE PAGE FAULT WORD JUMPL T2,SEILM4 ;INSURE AGAINST HARDWARE STORING A -1 P.F. WORD ANDI T2,37 ;CLEAR ALL BUT THE PAGE FAIL CODE TLNE T1,(XC.USR) ;PAGE FAULT IN EXEC MODE? JRST SEILM0 ;NO, PROCEED CAIN T2,PF.ABF ;WAS THE PAGE FAULT AN ADDRESS BREAK? JRST SEILM1 ;YES, REMEMBER IT AND GO AWAY JRST SEILM7 ;NO, EXEC ILL MEM REF, LOOK FOR ERJMP SEILM0: MOVE P,[XWD MJOBPD##,.JDAT+JOBPDL##] ;SETUP A PUSH DOWN LIST SKIPN .UPMP+.UPJOB STOPCD .,CPU,PFN ;++PAGE FAULT IN NULL JOB PUSH P,T1 ;SAVE USER'S PC CAIN T2,PF.ABF ;ADDRESS BREAK? JRST SEILM1 ;YES, GO PROCESS MOVE T4,T1 ;PC WORD INTO T4 FOR USRFLT HRRI T1,AP.ILM ;ILLEGAL MEMORY REFERENCE CAIN T2,PF.PRV ;WAS IT A PROPRIETARY VIOLATION? TROA T1,AP.PPV ;INDICATE PROPRIETARY VIOLATION (AVOID CALL TO USRFLT) PUSHJ P,USRFLT## ;SEE IF PAGE FAULT FOR A VM USER ; WILL NOT RETURN IF SO (DISPATCH TO USER) MOVE T2,.CPST2## ;RESTORE T2 JRST SEPDL1 ;GO SAY "ILL. MEM. REF." SEILM1: TLO T1,(IC.AFI) ;INHIBIT ADDRESS BREAK WHEN INSTRUCTION IS ; EXECUTED AGAIN EXCH J,.CPJOB## ;GET JOB PUSH P,W ;SAVE W IN CASE IN EXEC MODE PUSHJ P,FNDPDS## ;FIND THE PDB LDB T2,[POINT 9,.PDABS##(W),17] ;GET THE PROCEED COUNT SOSL T2 ;DECREMENT DPB T2,[POINT 9,.PDABS##(W),17] ;STORE IT BACK IF POSITIVE POP P,W ;RESTORE W JUMPG T2,SEILM3 ;DON'T BREAK IF PROCEED COUNT .GT. 0 MOVE T2,JBTSTS##(J) ;IS THIS A JACCT TLNN T2,JACCT ;JOB JRST SEILM6 ;NOT JACCT MOVE T2,JBTPPN##(J) ;YES, BUT IS CAME T2,FFAPPN## ; HE GOD? JRST SEILM3 ;NO-IGNORE BREAK SEILM6: EXCH J,.CPJOB## ;UNDO LAST EXCH TLNN T1,(XC.USR) ;PC IN USER MODE? JRST SEILM2 ;NO, REMEMBER BREAK AND GO AWAY MOVEM T1,.CPPC## ;STORE THE PC WITH IFA ON IFN FTPI,< MOVE J,.CPJOB## ;JOB NUMBER FOR PSISER SIGNAL C$ADRB ;SIGNAL THAT AN ADDRESS BREAK HAS OCCURED SKIPA ;USER DOESN'T WANT TRAP JRSTF @.CPPC## ;THE USER IS ENABLED, INTERRUPT HIM > ;END FTPI PUSH P,.CPPC## ;SAVE PC ON STACK PUSHJ P,TTYFUW## ;FIND THE USER'S TTY PUSHJ P,INLMES## ;REPORT THE ADDRESS BREAK ASCIZ / %Address break at user PC / HRRZ T1,(P) ;GET THE USER'S PC PUSHJ P,OCTPNT## ;TELL HIM WHERE THE BREAK OCCURED IFN FTPI,< PUSHJ P,PSIERR## ;PENDING INTERRUPT? JFCL PJRST ERRGOU## ;YES, GIVE IT TO THE USER > PJRST HOLDW## ;STOP THE JOB IN A CONTINUABLE STATE SEILM2: MOVEI T2,JS.ASA ;AC'S ARE IN THE SHADOW AREA BIT EXCH J,.CPJOB## ;JOB NUMBER TDNE T2,JBTSTS##(J) ;SAVE/GET IN PROGRESS? JRST SEILM3 ;YES, DON'T BOTHER THE USER WITH BREAKS ON THAT MOVEI T2,JS.ABP ;ADDRESS BREAK HAPPENED DURING UUO PROCESSING BIT IORM T2,JBTST2##(J) ;REMEMBER THAT THE BREAK HAPPENED SEILM3: EXCH J,.CPJOB## ;RESTORE J SEILM4: MOVEM T1,.UPMP+.UPMUP ;STORE PC WITH IC.AFI ON DMOVE T1,.CPST1## ;RESTORE T1 AND T2 JRSTF @.UPMP+.UPMUP ;GO AWAY AND TELL THE USER ABOUT THE BREAK ; AT UUO EXIT ;HERE IF AN ILL MEM REF OCCURED IN EXEC MODE, CHECK FOR ERJMP OR ;ERCAL BEFORE CALLING IT AN IME SEILM7: CONSO PI,PI.IPA ;AT INTERRUPT LEVEL? JRST SEJLM2 ;NO, UUO LEVEL, OK CONSO PI,PI.IPA-PI.IP7 ;YES - LEVEL 7? SKIPN .CPISF## ;YES, FROM SCHEDULER? JRST SEILME ;PI1 - PI6 OR NON-SCHEDULER PI7 SEJLM2: SKIPE .CPEJ1## ;NESTING? JRST SEILM8 ;YES, IT'S AN IME MOVE T2,.CPPFW## ;NO, GET PAGE FAULT WORD IFN FTPEEKSPY,< TLNE T2,(PF.USR) ;USER REFERENCE PUSHJ P,[PUSHJ P,SAVT## ;YES, SAVE ACS LDB T1,[POINT 9, T2,17] ;VIRTUAL PAGE NUMBER PUSHJ P,TSSPT## ;A SPY PAGE? POPJ P, ;NO PJRST UADERR##] ;YES,BLAME THE USER > DMOVEM T1,.CPEJ1## ;"TOP LEVEL", REMEMBER IN CASE WE NEST MOVEM T1,.CPEJ3## ;ALSO SAVE HERE FOR PSYCHOPATHIC CASES SKIP (T1) ;TOUCH PAGE FAULT PC LOCATION AND LDB T2,[POINT 13,1(T1),12] ;GET INSTRUCTION FOLLOWING ; IF THE PC JUMPED OFF INTO THE BOONIES ; THEN THIS WILL PAGE FAULT AND WE WILL ; KNOW WE HAVE A REAL IME CAIE T2,_-^D23 ;IS IT AN ERJMP? JRST SEILM8 ;NO, THEN WE HAVE AN IME MOVE T2,1(T1) ;GET ENTIRE ERJMP EXPRESSION MOVEM T2,.CPEJ4## ;AND SAVE IT WHERE WE CAN FIND IT DMOVE T1,.CPST1## ;RESTORE FULL AC SET MOVEI T1,@.CPEJ4## ;GET "E" OF ERJMP ; IF THIS IME'S (NOTE .CPEJ1 STILL ; NON-ZERO) THEN .CPEJ3 HAS ORIGINAL ; TRAP PC WHICH STARTED THIS MESS. HRRM T1,.CPAPC## ;SET FROM WHENCE TO CONTINUE MOVE T1,.CPST1## ;RESTORE T1 AGAIN SETZM .CPEJ1## ;CLEAR NESTING FLAG JRSTF @.CPAPC## ;AND GO PROCESS THE ERROR ;HERE ON NESTED IME, "RESTORE" THE FIRST IME AND STOPCD SEILM8: DMOVE T1,.CPEJ1## ;PAGE FAULT PC AND REASON WORDS MOVEM T1,.CPAPC## ;SET TRUE ERROR PC MOVEM T1,.UPMP+.UPMUP ;ALSO MAKE UPMP LOOK RIGHT MOVEM T2,.CPPFW## ;SET TRUE PAGE FAULT WORD MOVEM T2,.UPMP+.UPEPF ;ALSO MAKE UPMP LOOK RIGHT SEILME: SETZM .CPEJ1## ;CLEAR NESTING FLAG STOPCD .+1,JOB,IME, ;++ILL MEM REF FROM EXEC JRST SEILM4 ;AND DISMISS THE TRAP EXCABK::ANDCAM T1,JBTST2##(J) ;CLEAR BREAK HAPPENED IN EXEC MODE BIT PUSHJ P,FNDPDS## ;FIND THIS JOB'S PDB MOVSI T1,(OC.BCM) ;BREAK ON MUUO REFERENCES BIT TDNN T1,.PDABS##(W) ;IS THE USER INTERESTED? POPJ P, ;NO, GO AWAY IFN FTPI,< MOVE T2,.JDAT+JOBPD1## ;GET UUO PC MOVEM T2,.CPPC## ;STORE IT WHERE PSISER EXPECTS IT SIGNAL C$ADRB ;SIGNAL THAT AN ADDRESS BREAK OCCURED SKIPA ;USER DOESN'T WANT TRAP POPJ P, ;USER IS ENABLED, UUO EXIT WILL INTERRUPT TO HIM > IFN FTMP,< PUSHJ P,ONCPU0## ;MUST BE ON CPU0 TO WRITE A MESSAGE > PUSHJ P,TTYFUW## ;FIND THE USER'S TTY PUSHJ P,INLMES## ;REPORT THE ADDRESS BREAK ASCIZ / %Address break at exec PC / HRRZ T1,.UPMP+.UPMUP ;GET THE PC WHERE THE LAST BREAK OCCURED PUSHJ P,OCTPNT## ;TELL HIM THAT MOVEI T1,[ASCIZ/; UUO/] PUSHJ P,CONMES## MOVE T2,.JDAT+JOBPD1## ;GET THE UUO PC PUSHJ P,PCP## ;REPORT IT SO HE WILL KNOW WHAT UUO BROKE IFN FTPI,< PUSHJ P,PSIERR## ;PENDING INTERRUPT? JFCL POPJ P, ;YES > POP P,(P) ;POP OFF THE PUSHJ TO EXCABK PJRST HOLDW## ;AND STOP THE JOB IN A CONTINUABLE STATE SUILM::MOVEM T1,.UPMP+.UPMUO ;SAVE A TEMPORARY MOVE T1,.UPMP+.UPMUP ;GET ILM PC MOVE T2,.UPMP+.UPUPF ;GET THE PAGE FAIL WORD ANDI T2,37 ;PAGE FAIL CODE CAIN T2,PF.ABF ;ADDRESS BREAK? JRST SEILM0 ;YES, GO PROCESS IT MOVE T3,.UPMP+.UPUPF ;GET THE USER PAGE FAIL WORD MOVE T4,T1 ;MOVE THE PC TO T4 FOR USRFLT MOVE P,[XWD MJOBPD##,.JDAT+JOBPDL##] ;SETUP A PUSH DOWN LIST PUSHJ P,USRFLT## ;SEE IF PAGE FAULT FOR VM USER ; WILL NOT RETURN IF SO (DISPATCH TO PFH) MOVEI T3,AP.ILM ;SET ILM BIT FOR USER JRST SAROV3 ;FINISH UP SUPDLO::MOVE T1,.UPMP+.UPMUP ;GET ERROR PC MOVEI T3,AP.POV ;SET POV BIT FOR USER JRST SAROV3 ;FINISH UP ;ROUTINE TO SET HARDWARE AND SOFTWARE RELOCATION INFORMATION FOR CURRENT USER ;CALLING SEQUENCE: ; PUSHJ P,SETREL ; ... RETURN HERE ;J = CURRENT JOB NUMBER SETRLH::MOVE J,.CPJOB## ;J=CURRENT JOB NUMBER MOVEI T1,0 DPB T1,JBYHSS## ;FORCE MAP TO BE REDONE SETREL::MOVE J,.CPJOB## ;J = CURRENT JOB NUMBER SETRL1::MOVE T1,JBTADR##(J) ;T1 = PROT,,EVA ; OF THE FIRST PAGE OF THE LOW SEGMENT MOVEM T1,.CPADR## ;SET .CPADR FOR QUICK ACCESS AT APR LEVEL HLRZM T1,.CPREL## ;SET .CPREL FOR ADDR CHECKING IFN FTTRPSET,< SKIPE T2,.CPSTS## ;HAS TIMESHARING BEEN STOPPED VIA TRPSET? CAIE T2,(J) ;YES, IS IT THIS JOB? JUMPN T2,SETRLZ ;NO, DON'T CHANGE THE UBR > SKIPE J ;NULL JOB ALWAYS HAS A UPMP JUMPE T1,SETRLZ ;THERE IS NO UPMP IF THE JOB HAS NO CORE PUSHJ P,STEUB ;NO, SET THE USER BASE REGISTER JUMPE T1,SETRLZ ;IF NULL JOB OR CORE 0, DON'T STORE IN ; NON-EXISTANT JOB DATA AREA HLRZM T1,.UPMP+.UPHVA ;SET .UPHVA FOR ADDRESS CHECKING AT IRP LEVEL LDB T2,[POINT 9,T1,8];GET THE CURRENT SIZE LDB T1,JBYLSS## ;GET THE PREVIOUS SIZE OF THE LOW SEGMENT CAIE T1,(T2) ;IS IT THE SAME SIZE AS IT WAS THE LAST ; TIME THIS JOB WAS RUN? PUSHJ P,MAPLOW## ;NO, REDO THE MAP SKIPN T1,.UPMP+.UPREL ;HOLEY PROGRAM? HLR T1,JBTADR##(J) HRRZM T1,.JDAT+JOBREL## ;STORE HIGHEST CORE-UUO ADDRESS IN JOBREL SKIPL T1,JBTSGN##(J) ;JOB HAVE A REAL HIGH SEGMENT? SKIPA T1,JBTADR##(T1) ;YES HRLZS T1 ;SIZE OF SPY SEGMENT OR ZERO IF NOT SPY SEGMENT LDB T2,[POINT 9,T1,8];CURRENT SIZE -1 OF THE HIGH SEGMENT SKIPE T1 ;IS THERE A SPY OR HIGH SEGEMNT? ADDI T2,1 ;YES, ITS ACTUALLY ONE PAGE BIGGER LDB T1,JBYHSS## MOVSI T3,REDOMP!SEGMB TDNN T3,JBTSGN(J) CAIE T1,(T2) ;HAS THE HIGH SEGMENT SIZE CHANGED SINCE THE ; LAST TIME THIS JOB WAS RUN? PUSHJ P,MAPHGH## ;YES, REDO THE HIGH SEGMENT PART OF THE MAP MOVSI T1,REDOMP!SEGMB ANDCAM T1,JBTSGN(J) SETRLZ: PUSHJ P,FDNJP## ;FIND THE NULL JOB'S PDB MOVE T3,T1 ;SAVE THE ADDRESS OF THE NULL JOB'S PDB PUSHJ P,FNDPDS## ;FIND THE CURRENT JOB'S PDB HRRZ T1,JBTUPM##(J) ;PAGE NUMBER OF THE CURRENT JOB'S UPMP JUMPE T1,SETRL2 ;DON'T CHANGE ANYTHING IF THERE ISN'T ONE MOVSI T1,<(PG.LUB)>(T1) IFN FTRTTRP,< MOVEM T1,.CPDTO## ;SAVE FOR RTTRP INTERRUPT LEVEL USE > TLO T1,(PG.ACE+PG.AC1) ;USER ADDRESS COMPARE ENABLE AND USER AC SET 1 .SKIPE T2,.PDABS##(W) ;DOES THE USER HAVE ADDRESS BREAK SETTINGS? TLNN T2,(OC.ABE) ;YES, IS HE ENABLED FOR BREAKS MOVE T2,[EXP OC.FEP+CURJOB##] ;NO, DISPLAY JOB NUMBERS DATAO PAG,T1 ;SETUP THE UBR TLZ T2,777(OC.BSU) ;CLEAR PROCEED COUNTER AND SET BY UUO .SKIPL .PDABS##(T3) ;CAN USERS USE ADDRESS BREAK? DATAO PTR,T2 ;YES, SETUP BREAK CONDITIONS AND BREAK ADDRESS SETRL2: SKIPN JBTADR##(J) ;JOB HAVE CORE IN CORE? TDZA T1,T1 ;NO, MUST BE THE NULL JOB OR CORE 0 MOVE T1,.JDAT+JOBENB## ;JOB'S APR ENABLE BITS PJRST SETCNA## ;SETUP APR ENABLE BITS FOR USER ; NO ENABLES IF NULL JOB OR NO CORE IN CORE ;ROUTINE TO SETUP USER AND EXEC BASE REGISTERS FOR A JOB ;CALLING SEQUENCE: ; MOVE J,JOB NUMBER ; PUSHJ P,STEUB MKADD:: CAME J,.USJOB ;JOB ALREADY ADDRESSABLE? STEUB:: CAILE J,JOBMAX## ;IS THIS A LOW SEGMENT? POPJ P, ;NO, THE UBR MUST ALREADY BE SETUP ; OR DOESN'T NEED TO BE (ADDRESSES WILL BE ; MAPPED THROUGH THE EXEC MAP) PUSH P,T1 ;SAVE A TEMPORARY HRRZ T1,JBTUPM##(J) ;T1 = THE PAGE NUMBER OF THE USER PAGE MAP PAGE TRNN T1,17777 ;IS THERE A UPMP JRST TPOPJ## ;NO, DON'T CLOBBER UBR MOVSI T1,<(PG.LUB+PG.AC1)>(T1) DATAO PAG,T1 ;SET FOR CURRENT USER AND CLEAR THE AM JRST TPOPJ## ;RESTORE T1 AND RETURN SUBTTL IOCSS - I/O SERVICE SUBROUTINES (UUOCON AND DEVICE ROUTINES) ;ROUTINE TO SAVE AND OPTIONALLY SET UP THE USER BASE REGISTER ; AND RESTORE IT ON A CPOPJ OR CPOPJ1 RETURN ;CALLING SEQUENCE: ; PUSHJ P,SVEUB ;TO SAVE USER BASE REGISTER ;OR ; PUSHJ P,SVEUB ;TO SAVE USER BASE REGISTER AND SETUP ; ;USER BASE REGISTER FOR JOB IN J ;ALWAYS RETURN HERE SVEUF:: PUSH P,T1 ;SAVE A TEMPORARY DATAI PAG,T1 ;GET THE USER AND EXEC BASE REGISTERS PUSH P,J ;SAVE J LDB J,PJOBN## ;GET THE JOB NUMBER OF JOB CURRENTLY USING ; THIS DEVICE PUSHJ P,STEUB ;SETUP THE UBR SO CURRENT JOB IS ADDRESSABLE POP P,J ;RESTORE J JRST SSEU1 ;SAVE THE PREVIOUS CONTENTS OF THE UBR AND EBR SVEUB:: PUSH P,T1 ;SAVE A TEMPORARY DATAI PAG,T1 ;GET THE CONTENTS OF THE USER AND EXEC BASE REGISTERS PUSHJ P,STEUB ;SETUP THE UBR FOR THE JOB WHOSE JOB NUMBER ; IS IN J JRST SSEU1 ;SAVE THE PREVIOUS CONTENTS OF THE UBR AND THE EBR SSEUB:: PUSH P,T1 ;SAVE A TEMPORARY DATAI PAG,T1 ;GET THE CONTENTS OF THE USER AND EXEC BASE REGISTERS SSEU1: EXCH T1,-1(P) ;GET THE CALLER'S PC AND SAVE THE CONTENTS ; OF THE UBR AND EBR MOVEM T1,1(P) ;SAVE THE CALLER'S PC IN A TEMPORARY LOCATION ; ON THE STACK POP P,T1 ;RESTORE T1 TO ITS CONTENTS ON ENTRY PUSHJ P,@2(P) ;RETURN TO THE CALLER LEAVING .+1 ON THE ; STACK SO WHEN THE CALLER DOES A POPJ OR ; A CPOPJ1, CAN RESTORE THE PREVIOUS CONTENTS ; OF THE UBR AND THE EBR CAIA ;CPOPJ RETURN AOS -1(P) ;CPOPJ1 RETURN - BUMP RETURN PC EXCH T1,(P) ;GET THE PREVIOUS CONTENTS OF THE UBR TDO T1,[EXP PG.LUB+PG.LEB] DATAO PAG,T1 ;RESTORE THE UBR AND THE EBR JRST TPOPJ## ;RESTORE T1 AND RETURN ;ROUTINE TO CONVERT AN IOWD TO ABSOLUTE IOWDS ;FOLLOWING THE PAGING OF A JOB ;CALLING SEQUENCE: ; MOVE T2,IOWD ; MOVEI P1,0 ;FIRST CALL ; MOVE P3,LOC OF CHANNEL DATA BLOCK ; LH(P3)=1 IF STORE EXPECTED CHAN TERM WORD ; MOVE P4,FRAME-COUNT,,CHARS/WD IF DX10 CHL ; PUSHJ P,MAPIOW ; RETURN HERE IF NOT ENOUGH MONITOR FREE CORE ; RETURN HERE - P2=ADDRESS OF FIRST IOWD ; P1=WHERE NEXT IOWD WILL BE STORED ; LH(P2)=LOC WHERE IOWD WAS STORED, IF A DX10 MAPIO:: TLNN T2,-1 ;0 OR CHANNEL JUMPS ARE ILLEGAL STOPCD CPOPJ##,DEBUG,IEZ, ;++IOWD EQUALS ZERO PUSHJ P,SVEUB ;SAVE AND SETUP UBR PUSH P,U ;SAVE U LDB U,[POINT 2,CHB22B##(P3),1] ;GET CHL TYPE INFO HLL U,P4 ;PRESERVE FRAME-COUNT PUSH P,T1 ;SAVE ALL ACS THAT ARE USED SINCE THEY PUSH P,P4 ; ARE PROBABLY IMPORTANT TO THE CALLERS PUSH P,P3 ; OF MAPIOW PUSH P,T2 ; .. PUSH P,T3 ; .. PUSH P,T4 ; .. JUMPN P1,MAPIO1 ;P1 IS NON-ZERO IF NOT THE FIRST CALL PUSHJ P,GCH4WD ; .. JRST MAPIO9 ;NONE AVAILABLE MOVE P1,T1 ;ADDRESS OF THE FOUR WORD BLOCK MOVE P2,T1 ;ADDRESS OF THE IOWD LIST HRLI P1,-3 ;THE NUMBER OF WORDS LEFT IN THIS BLOCK SETZM 3(P1) ;ZERO THE LAST WORD OF THE BLOCK MAPIO1: PUSHJ P,CHKMOR ;GET ANOTHER FOUR WORD BLOCK AND LINK IT ; TO THE CURRENT BLOCK IF ABOUT TO USE ; THE LAST WORD OF THE CURRENT BLOCK JRST MAPIO8 ;NO MORE FOUR WORD BLOCKS MOVE P4,-2(P) ;RESTORE THE IOWD TO P4 HRRZ T2,P4 ;ADDRESS-1 WHERE I/O WILL START MOVE T3,DEVMOD(F) IFE FTSPL,< TLNN T3,DVDSK ;IF A DSK > IFN FTSPL,< SKIPL DEVSPL(F) ;SPOOLED DDBS ARE ALWAYS A DSK TLNE T3,DVDSK ;IS A DSK CAIA > JUMPN T3,MAPI1B JUMPGE S,MAPI1B SKIPN DINITF## CAIE T2,@.UPMP+.UPMBF ;WE KNOW BITS 13-17 ARE ZERO JRST MAPIO6 ADDI T2,<.MCFV-.FPMC>+1 JRST MAPI1D MAPI1B: MOVEI T2,1(P4) ;STARTING ADDRESS MAPI1D: LSH T2,W2PLSH## ;CONVERT TO PAGE NUMBER ROT T2,-1 ;SET UP A BYTE POINTER TO THE PAGE IN THE UPMP ADDI T2,.UPMP TLZE T2,400000 TLOA T2,() TLO T2,() MOVE P3,T2 ;SAVE POINTER IN P3 MOVE T2,P4 ;T2 AND P4 = IOWD HLROS P4 ;P4 = -WORD COUNT ADDI T2,1 ;POINT AT REAL ADR MAPIO2: LDB T3,P3 ;T3 = CURRENT ABSOLUTE PAGE NUMBER TRNN T3,PM.ACC SKIPGE USRHCU## ;IF A SAVE IS IN PROGRESS, SKIPA ; THEN, THIS IS OK JRST S..AAO ;ACCESS ALLOWED OFF ; IOWD HAS BEEN ADDRESS CHECKED) MOVEI T1,0 ;T1 = AMOUNT ACCUMULATED SO FAR LSH T3,P2WLSH## ;MOVE PAGE NUMBER TO THE HIGH ORDER THIRTEEN ; BITS OF THE ADDRESS ANDI T2,PG.BDY## ;GET THE STARTING WORD ADDDESS WITHIN THE PAGE ADD T2,T3 ;T2 = ABSOLUTE ADDRESS (IOWD STYLE) SUBI T2,1 ;MAKE AN IOWD PUSH P,T2 ;SAVE THE ADDRESS ANDI T2,PG.BDY## ;EXTRACT THE WORD NUMBER SUBI T2,PAGSIZ##-1 ;CALCULATE THE NUMBER OF WORDS TO DO INTO THIS PAGE SKIPN T2 ;IF ITS ZERO DO A WHOLE PAGE WORTH MAPIO3: MOVNI T2,PAGSIZ## ; .. SUB P4,T2 ;ADD -NUMBER OF WORDS ON THIS PAGE TO ; IOWD WORD COUNT ADD T1,T2 ;ACCUMULATE IN TOTAL WORD COUNT JUMPGE P4,MAPIO4 ;JUMP IF THE ORIGIONAL WORD COUNT IS EXHAUSTED SETZ T3, ;SET T3 SO TEST WILL FAIL IF 22-BIT CHAN AND SKIPE U ; NO ROOM FOR ANOTHER PAGE IN IOWD CAML T1,[EXP -37777+PAGSIZ##] ;OTHERWISE SET T3=CURRENT PAGE LDB T3,P3 ;T3 = CURRENT PAGE NUMBER WITHIN SEGMENT ILDB T4,P3 ;T4 = NEXT PAGE NUMBER WITHIN SEGMENT TRNN T4,PM.ACC ;ACCESS ALLOWED ON? STOPCD .,JOB,AAO, ;++ACCESS ALLOWED IS OFF TRZ T3,760000 ;CLEAR ACCESS BITS TRZ T4,760000 ;CLEAR OUT THE ACCESS BITS CAIN T4,1(T3) ;ARE THE TWO PAGES ADJACENT IN PHYSICAL MEMORY? JRST MAPIO3 ;YES, CONTINUE ON CURRENT IOWD MOVEI T2,0 ;T2 = FIRST ADDRESS POP P,(P1) ;STORE THE IOWD ABSOLUTE ADDRESS PUSHJ P,DXFIX ;ADJUST IOWD IF A DX10 JRST MAPIO8 ;NO SPACE JUMPL U,MAPIO7 ;GO IF FRAMECOUNT EXHAUSTED AOBJN P1,MAPIO2 ;CONTINUE IF THERE IS ROOM IN THE FOUR WORD BLOCK PUSHJ P,GETMOR ;GET ANOTHER FOUR WORD BLOCK JRST MAPIO8 ;WHOOPS! NONE AVAILABLE MOVEI T2,0 ;START AT WORD NUMBER ZERO ON THIS PAGE JRST MAPIO2 ;MAP THE REST OF THE IOWD MAPIO4: POP P,(P1) ;STORE THE IOWD ABSOLUTE ADDRESS ADD P4,T1 ;ADD THE RESIDUAL WORD COUNT TO THE ACCUMULATED ; WORD COUNT MOVE T1,P4 ;PUT WD CNT INTO T1 PUSHJ P,DXFIX ;PERFORM FIXUPS FOR DX10 JRST MAPIO8 ;OUT OF SPACE JRST MAPIO7 ;AND GIVE THE WIN RETURN MAPIO6: MOVEM T2,0(P1) ;STORE ADDRESS HLRE T1,P4 ;GET WORD COUNT PUSHJ P,DXFIX ;FIDDLE WITH DX10 IOWDS JRST MAPIO8 ;NO ROOM ; THE ALREADY ABSOLUTE IOWD AND RETURN ;AND FALL INTO MAPIO7 ;MAPIO6 FALLS INTO HERE MAPIO7: AOBJN P1,.+1 ;BUMP THE POINTER TO THE NEXT FREE WORD SETZM (P1) ;ZERO IT SO THE LIST IS TERMINATED AOS -7(P) ;SET FOR SKIP (WIN) RETURN MAPIO8: SKIPGE -3(P) ;IF WE WANT IT STORED, TRNE U,1 ;TYPE 0 OR 2 CONTROLLER? JRST MAPIO9 ;NO, DON'T DO NEXT HRRZS U ;CLEAR POSSIBLE FRAMECOUNT LSH U,-1 MOVE T3,P1 ;GET ADDR OF LAST IOWD FOR BYTE PTR'S LDB T1,ADRPT2##(U) ;GET ADDR FIELD FROM LAST IOWD HLRO P4,-1(T3) ;WORD COUNT ASH P4,@ASH22B##(U) ;4 BITS DON'T COUNT IF 22-BIT SUB T1,P4 ;DETERMINE ENDING DATA ADDRESS DPB P1,ADRPT4##(U) ;PUT ADDR OF END OF IOWD LIST MOVE P3,-3(P) MOVEM T1,CHNTCW##(P3) MAPIO9: POP P,T4 ;RESTORE ACS POP P,T3 ; .. POP P,T2 ; .. POP P,P3 ; .. POP P,P4 ; .. POP P,T1 ; .. PJRST UPOPJ## ;GIVE WIN OR LOSE RETURN ;SUBROUTINE TO CHECK TO SEE IF THE CURRENT FOUR WORD BLOCK IS EXHAUSTED ; AND IF SO GET ANOTHER ONE IF ANY ARE AVAILABLE. IF THE NEXT FOUR WORD ; BLOCK IT OBTAINS IS ADJACENT TO THE CURRENT ONE, IT SIMPLY RETURNS. IF ; IT IS NOT, A LINK WORD LINKING THE CURRENT FOUR WORD BLOCK TO THE ; NEW FOUR WORD BLOCK IS SETUP IN THE FOURTH WORD OF THE CURRENT BLOCK ;CALLING SEQUENCE: ; MOVE P1,AOBJN POINTER TO CURRENT BLOCK ; PUSHJ P,CHKMOR ; ... RETURN HERE IF NO MORE FOUR WORD BLOCKS ; ... RETURN HERE IF CURRENT FOUR WORD BLOCK NOT FILLED OR ; NEXT FOUR WORD BLOCK OBTAINED ;P1 = AOBJN POINTER TO CURRENT OR NEW BLOCK CHKMOR::JUMPL P1,CPOPJ1## ;CONTINUE IF ANY WORDS LEFT IN THIS BLOCK GETMOR::PUSHJ P,GCH4WD ;GET 1 CORE BLOCK POPJ P, ;NO MORE AVAILABLE CAIE T1,1(P1) ;IS THIS BLOCK ADJACENT TO THE LAST BLOCK? JRST GETMR1 ;NO, ADD A LINK HRLI P1,-4 ;YES, FOUR WORDS LEFT TO GO (LAST WORD IN ; THE LAST BLOCK AND THREE WORDS IN NEW BLOCK) JRST CPOPJ1## ;RESTORE T2 AND GIVE OK RETURN GETMR1: TRC U,3 TRCN U,3 ;CHECK CHL TYPE HRLI T1,CCHJGO## ;DX10 STYLE CHL JUMP MOVEM T1,0(P1) ;LINK TO THE NEW BLOCK MOVE P1,T1 ;P1 = POINTER TO NEW BLOCK HRLI P1,-3 ;NUMBER OF WORDS LEFT TO GO IN THE CURRENT BLOCK JRST CPOPJ1## ;AND SKIP RETURN ;ROUTINE USED TO HANDLE 22-BIT CHNLS AND PERFORM IOWD TRANSFORMATIONS ;FOR THE DX10 TAPE CHL. CALLING SEQUENCE: ; MOVE T1,-WDS TO XFER ; MOVE P1,ADDRS OF CURRENT IOWD ; CHARS/WD WAS FOUND IN THE ORIGINAL CALL TO MAPIO ; PUSHJ P,DXFIX ; ... ;RETURN HERE IF NO MORE FREE SPACE ; ... ;RETURN HERE IF OK DXFIX: HRRZ T4,U CAIE T4,3 ;CHECK CHL TYPE JRST [DPB T1,WDCPNT##(U) JRST CPOPJ1##] ;HANDLE NON-DX10 CHLS MOVE T4,-5(P) ;RESTORE CHAR/WD IMULI T1,0(T4) ;CONVERT TO BYTE COUNT AOS 0(P1) ;DX10 LIKES ADDRS RATHER THAN ADDRS-1 HLRZ T3,U ;FRAME-COUNT USER SET JUMPE T3,DXFIX0 ;NONE MOVNS T3 CAML T3,T1 ;MORE THAN HE WANTS? MOVE T1,T3 ;YES, GET WHAT WAS REQUESTED HRLZ T3,T1 ;FRAMECOUNT ADDB T3,U ;UPDATE MAX LEFT TLNN T3,-1 ;ANY LEFT? HRROS U ;NO, INDICATE WE'RE DONE DXFIX0: CAML T1,[-17777] ;ROOM FOR THIS JRST DXFIX2 ;YES - JUST STORE AND EXIT MOVE T3,MCHTAB(T4) ;MAX CHARS / XFER CMD SUB T1,T3 ;SUBTRACT MAX FOR THIS ONE DPB T3,WDCPNT##(U) ;STORE IN IOWD PUSH P,0(P1) ;SAVE PNTR AOBJN P1,DXFIX1 ;SEE IF ROOM FOR MORE PUSH P,T1 ;NO -SAVE COUNT PUSHJ P,GETMOR ;GET MORE SPACE JRST DXFIX3 ;RAN OUT OF SPACE MOVEI T2,0 ;RESTORE T2 POP P,T1 ;RESTORE COUNT DXFIX1: POP P,T3 ;GET LAST POINTER MOVE T4,-5(P) ;RESTORE T4 (CHARS/WD) ADD T3,MWDTAB(T4) ;ADD MAX WORDS OFFSER MOVEM T3,0(P1) ;NEW PARTIAL PNTR JRST DXFIX0 ;PROCEED DXFIX2: DPB T1,WDCPNT##(U) ;STORE RESIDUE HRL P2,P1 ;LOCATION OF IOWD JRST CPOPJ1## ;SUCCESS RETURN DXFIX3: POP P,T1 ;PRUNE PDL JRST TPOPJ## ;PRUNE & EXIT (FAIL) ;THE BYTE PACKING MODES OF THE DX10 WILL ALLOW 4,5 & 6 BYTES / WORD ;THESE TABLES ARE USED TO TRANSLATE THIS INFO INTO 1) THE MAX CHARS ;THAT WILL EXACTLY FILL THE 2) MAX NO. OF WDS PER IOWD ;ALLOWING 2^13-1 BYTES / IOWD. MCHTAB=.-4 -<17777/4>*4 ;4 BYTE/WD = 8188 BYTES -<17777/5>*5 ;5 BYTE/WD = 8190 BYTES -<17777/6>*6 ;6 BYTE/WD = 8190 BYTES MWDTAB=.-4 17777/4 ;4 BYTE/WD = 2047 WDS 17777/5 ;5 BYTE/WD = 1638 WDS 17777/6 ;6 BYTE/WD = 1365 WDS ;ROUTINE TO RETURN FREE CORE USED FOR MAPPING IOWDS. ;CALLING SEQUENCE: ; MOVE T1,ADDRESS OF IOWD LIST ; PUSHJ P,RTNIOW ; ALWAYS RETURN HERE RTNIOW::PUSHJ P,SAVE1## ;SAVE P1 HRRZ P1,T1 ;P1 = ADDRESS OF THE IOWD LIST RTNIO1: MOVEI T1,1 ;GIVE BACK ONE FOUR WORD BLOCK HRRZ T2,P1 ;ADDRESS OF THE BLOCK MOVE T3,3(P1) ;LAST WORD OF BLOCK TLNN T3,-1 ;AN IOWD? SKIPA P1,T3 ;NO, THEN THIS IS THE LAST BLOCK ; OR A LINK TO THE NEXT BLOCK ADDI P1,4 ;ADDRESS OF THE NEXT BLOCK ; (ITS ADJACENT TO THE CURRENT BLOCK) PUSHJ P,RCH4WD ;RETURN BLOCK TO MONITOR FREE CORE JUMPE P1,CPOPJ## ;JUMP IF THIS IS THE LAST BLOCK JRST RTNIO1 ;GIVE UP ALL THE BLOCKS ;ROUTINE TO OBTAIN A LOWER-CORE 4-WORD BLOCK GCH4WD::MOVE T1,NOIOWD## ;IF WE DON'T HAVE MUCH IOWD SPACE CAMGE T1,NUMKON## ; ONLY GIVE AN IOWD JUMPN P1,CPOPJ## ; FOR THE INITIAL IOWD MOVEI T1,1 ;JUST WANT 1 BLOCK MOVEI T2,LOWPTR## ;POINT TO LOWER-CORE FREE-CORE TABLE PUSHJ P,GETBIT## ;GET, SET THE BIT POPJ P, ;NONE AVAILABLE, LOSE SOS NOIOWD## ;1 LESS IOWD BLOCK LSH T1,2 ;CONVERT TO 4-WORD STYLE ADD T1,LOWLOC## ;CONVERT TO ACTUAL ADDRESS SETZM 3(T1) ;ZERO THE LAST WORD OF THE CURRENT BLOCK PJRST CPOPJ1## ;AND TAKE GOOD RETURN ;ROUTINE TO RETURN LOWER-CORE 4-WORD BLOCKS RCH4WD::SUB T2,LOWLOC## ;CONVERT TO RELATIVE ADDRESS LSH T2,-2 ;/4 TO CONVERT TO BITS IDIVI T2,^D36 ;COMPUTE WORD ADR, POSITION IN WORD HRLS T2 ADD T2,LOWPTR## ;SET AOBJN POINTER FOR SETZRS ADDM T1,NOIOWD## ;1 MORE IOWD BLOCK PJRST SETZRS## ;CLEAR THE BITS AND RETURN SUBTTL ERRCON - ERROR HANDLING MODULE ;SUBROUTINE TO SWEEP MEMORY TO FIND ADDRESS AND CONTENTS OF BAD WORDS ;IT CALLS CPU INDEPENDENT SUB.(PARERR) TO RECORD DATA ON EACH BAD WORD ;CALL: PUSHJ P,@.CPMPS## ; ALWAYS RETURN WHEN SWEEP OVER (EVEN IF SERIOUS ERROR) ;SWEEP CORE IN ASCENDING ADDRESSES EVEN THOUGH SLOWER, SO DATA STORED ASCENDING ; FOR ERROR REPORTING WITH DAEMON CPIMPS::PUSHJ P,MAPLOC## ;GET EXEC MAP SLOT MOVE W,T1 ;SAVE BYTE POINTER TO EXEC MAP SLOT MOVEI P3,PM.ACC+PM.WRT;START AT PAGE 0, ACCESSIBLE AND WRITEABLE LDB T4,[POINT 14,MEMSIZ##,26] ;T4=NUMBER OF PAGES TO SCAN SKIPA P4,[POINT 1,NXMTAB##] ;BYTE POINTER TO NXM TABLE MPSLP1: AOS P3 ;STEP TO NEXT PAGE SOJL T4,MPSLP5 ;RESTORE T1 AND RETURN IF SCANNED ALL OF MEMORY ILDB T1,P4 ;DOES THIS PAGE EXIST? JUMPN T1,MPSLP1 ;IF NOT, GO BACK FOR NEXT DPB P3,W ;MAP THE CURRENT PAGE MOVE P1,T3 ;EVA FOR BEGINNING OF PAGE CLRPGT (0) ;CLEAR ASSOCIATIVE MEMORY FOR NEW MAPPING MOVEI T2,PAGSIZ## ;NO. OF WORDS/PAGE TO SCAN SETOM .CPPSP## ;SET SWEEPING FLAG MPSL1A: MOVEI T1,5 ;NO. OF SOJG'S TO WAIT FOR INTERRUPT TO HAPPEN MOVE P2,(P1) ;TEST NEXT LOCATION CPIMPI::SOJG T1,. ;DELAY HERE SO INTERRUPT PC POINTS HERE MPSLP2: SOJLE T2,MPSLP1 ;IF CURRENT PAGE DONE, MAP NEXT AOJA P1,MPSL1A ;GO TEST NEXT WORD IN PAGE ;HERE ON BAD WORD FOUND (NXM OR PARITY) - INTERRUPT HAPPENED AND ADDED 3 TO PC MAP T1,(P1) ;GET THE PHYSICAL PAGE THAT BAD WORD IS IN PUSH P,P1 ;SAVE THE EVA PUSH P,T2 ;SAVE THE WORD NUMBER IN CURRENT PAGE PUSH P,T3 ;SAVE THE POSITION IN THE MAP PUSH P,T4 ;SAVE # OF PAGES TO SCAN DPB T1,[POINT 13,P1,26] ;FORM PHYS. ADDRESS OF BAD WORD PUSHJ P,CPIASN## ;CONVERT TO SEG NUMBER IN J TDZA T1,T1 ;INDICATE NO ERROR IN MONITOR OR A JOB SETO T1, ;INDICATE AN ERROR IN MONITOR OR A JOB MOVE P2,.CPTBD## ;GET BAD DATA WORD STORED BY THE TRAP ROUTINE PUSHJ P,PARRBD## ;RECORD BAD DATA POP P,T4 ;RESTORE T4 POP P,T3 ; AND T3 POP P,T2 ; AND T2 POP P,P1 ; AND P1 JRST MPSLP2 ;GO CONTINUE THE SWEEP MPSLP5: SETZM .CPPSP## ;CLEAR SWEEPING FLAG PUSHJ P,UNMAP## ;RESTORE EXEC MAP SLOT POPJ P, ;AND RETURN $LIT KIEND: END