Trailing-Edge
-
PDP-10 Archives
-
tops10_703a_sys_atpch16_bb-fr67f-bb
-
ksser.x16
There are 2 other files named ksser.x16 in the archive. Click here to see a list.
TITLE KSSER - KS20 PROCESSOR DEPENDENT CODE V116
SUBTTL DMCC/DBD 17 JUN 86
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<1978,1986>
;COPYRIGHT (C) 1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.
XP VKSSER,116
;TRACKS VERSION 274 OF KLSER
ENTRY KSSER ;LOAD KSSER IF LIBRARY SEARCH
KSSER:
SUBTTL TRAP HANDLING AND CONTEXT SWITCHING
;HERE TO PROCESS USER ARITHMETIC OVERFLOW TRAPS
SAROVF::
DMOVE T1,.USMUO ;GET PC DBL WRD
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: TLNE T2,MXSECN ;IN A NON-ZERO SECTION?
JRST SAROV9 ;CAN'T TRAP IT THIS WAY THEN
HLLM T1,.JDAT+JOBTPC## ;SAVE OLD PC
HRRM T2,.JDAT+JOBTPC## ;..
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
MOVSI T3,(JFCL) ;NOP
MOVEM T3,.USAOT ;IGNORE ARITHMETIC TRAPS
MOVEI T3,UP.PDT
MOVEM T3,.USPDT ;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(T2)
CAIN T3,-1(T2)
JRST SAROV7 ;YES
HRR T2,.JDAT+JOBAPR## ;GET USER'S TRAP ADDRESS
TLZ T1,(XC.OVF+XC.FOV+XC.FUF+XC.NDV+IC.BIS)
TLO T1,(XC.USR) ;INSURE PUBLIC AND USER MODE IS SET
SAROV6: DMOVEM T1,.USMUO ;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
USERAC ;SET USER AC BLOCK
XJRSTF .USMUO ;EXIT TO THE USER'S TRAP HANDLER
SAROV7: MOVEI T3,XP.LTH ;STUCK IN LOOP BIT
SAROV9: DMOVEM T1,.CPAPC## ;SAVE OLD PC FOR ERROR MESSAGE
HRRM T3,.CPAEF##
JRST SEPDL3
;HERE TO PROCESS EXEC STACK OVERFLOW TRAPS
SEPDLO::EXCH T1,.USMUP ;GET THE PC
MOVEM T1,.CPAPC##+1 ;STORE PC
HLLZ T1,.USMUO ;FLAGS
MOVEM T1,.CPAPC## ;SET AS ERROR PC FOR ERRCON
TLNN T1,(XC.USR) ;IN USER MODE?
JRST DOPDL ;NOPE, EXEC MODE, TAKE A DUMP
HRRI T1,AP.POV ;SET PUSH DOWN OVERFLOW FLAG
SEPDL1: HRRM T1,.CPAEF## ;IN .CPAEF SO ERRCON WILL GET CALLED
MOVE T1,.USMUP ;RESTORE T1
SEPDL3: SETOM .CPSCF## ;SET FORCED RESCHEDULING FLAG
SETOM .CPCKF## ;AND CLOCK FLAG
WRPI CLKBIT## ;REQUEST A CLOCK INTERRUPT
JRST . ;WAIT UNTIL CLOCK LEVEL HAPPENS AND THE JOB
; IS STOPPED IN USER MODE.
DOPDL:: EXCH T1,.USMUP ;SAVE PC AND RESTORE T1
MOVEM P,@.CPEPL## ;SAVE OLD P
HRRZS P ;SEE IF
CAMLE P,SYSSIZ## ;UUO OR INTERRUPT LEVEL
XJRST [MCSEC1+EXTPDL##] ;UUO, TRY TO EXTEND THE PDL
JRST EPOSTP## ;CAN'T RECOVER ON INTERRUPT LEVEL
;HERE TO PROCESS PAGE FAILURE TRAPS
SEILM:: RDPI .CPTPI## ;SAVE THE PI STATE
WRPI PI.OFF ;NOW INSURE THAT PI'S ARE OFF
RDUBR .CPTCX## ;SAVE THE TRAP CONTEXT
EXECAC ;WANT MONITOR'S AC BLOCK
JRSTF @[IC.UOU+.+1] ;INSURE USRIOT IS ON SO PXCT WORKS
MOVEM T1,.CPSTT## ;SAVE T1 TEMPORARILY
LDB T1,[POINT 5,.USPFW,5] ;PICK UP PF CODE
CAIGE T1,20 ;IS THIS A REAL PAGE FAULT?
JRST SEILMA ;YES--GO PROCESS IT
CAIN T1,PF.IOP ;IS IT A UBA FAILURE?
JRST SEILMU ;YES, PROCESS
CAIL T1,PF.PAR ;IS IT A PARITY OR NXM TRAP?
JRST PRTRP ;YES--GO PROCESS
CAIN T1,PF.PTP ;IS IT PAGE TABLE PARITY?
JRST PTPAR ;YES--GO PROCESS
STOPCD .,CPU,IPC ;++ILLEGAL PAGE FAILURE TRAP CODE
;HERE ON A UNIBUS ADDRESSING FAILURE
;A USER MODE FAILURE CAN OCCUR IF THE USER HAS IOT, AND MAKES A
;STRAY REFERENCE. WE DON'T WANT TO KILL THE SYSTEM. ALLOW THE
;USER TO INTERCEPT (NOT APRENB, BUT PSI) SO CAN CHECK WHETHER A
;DEVICE IS PRESENT.
SEILMU: DMOVEM T2,.CPST1## ;SAVE SOME MORE ACS
DMOVE T1,.USPFP ;FETCH THE PC THAT FAILED
SKIPE .USJOB## ;IF NULL JOB, IT'S EXEC MODE
TLNN T1,(XC.USR) ;USER MODE?
STOPCD .,STOP,UAF,DIEUAF ;++UNIBUS ADDRESSING FAILURE
DMOVEM T1,.CPAPC## ;USER MODE, CAN SIMPLY STOP JOB (USER HAS IOT)
MOVE T1,.USPFW ;GET THE ADDRESS THAT FAILED
MOVEM T1,.USMUP ;SAVE IT IN CASE NON-EXISTANT UBA
TLZ T1,^-17 ;KEEP ONLY THE UBA NUMBER
HRRI T1,UNBSTW ;POINT TO THE UBA STATUS REGISTER
MOVEI T3,UBNOGD ;GET PAGE FAIL HANDLER
EXCH T3,.USPFN+1 ;IN CASE OF ILLEGAL UBA
MOVEI T2,UNBNED!UNBTMO ;NON-EXISTANT DEVICE AND TIMEOUT
BSIO T2,(T1) ;CLEAR THE BITS
MOVEM T3,.USPFN+1 ;RESTORE THE USUAL PAGEFAIL HANDLER
DMOVE T2,.CPST1## ;AND THE EXTRA ACS
MOVE T1,.CPSTT## ;RESTORE T1
EXCH T1,.USMUP ;AND PUT IT WHERE SEPDL1 WANTS IT
MOVEM T1,.USPFW ;RESTORE ORIGINAL PFW IN CASE OF PSI TRAP
MOVEI T1,AP.ILM ;ILL MEM REF BIT
WRPI PI.ON ;RESTORE PI SYSTEM
JRST SEPDL1 ;AND GIVE ?ILL MEM REF AT PC MUMBLE
DIEUAF: PUSHJ P,INLMES## ;ADD SOME TEXT
ASCIZ /UBA = /
LDB T1,[POINT 3,.USPFW,17] ;GET UBA NUMBER
PUSHJ P,PRTDI8## ;PRINT IT
PUSHJ P,INLMES## ;MORE TEXT
ASCIZ /, register address = /
HRRZ T1,.USPFW ;GET ADDRESS
PJRST PRTDI8## ;PRINT AND RETURN
;HERE ON A PARITY OR NXM TRAP
PRTRP: SKIPE .CPPSP## ;CORE SWEEP IN PROGRESS?
JRST SWTRP ;YES, JUST SAVE LOCATION OF FAILURE AND DISMISS
EXCH T1,.CPSTT## ;RESTORE T1 AND SAVE TRAP CODE
MOVEM 17,.CPA17## ;SAVE AC 17
MOVEI 17,.CPA00## ;MAKE BLT POINTER
BLT 17,.CPA17##-1 ;SAVE AC'S IN CPU DATA BLOCK
MOVE P,.CPEPD## ;SET UP ERROR STACK
MOVE J,.CPJOB## ;SET UP J WITH CURRENT JOB RUNNING
MOVE T1,JBTPPN##(J) ;GET ITS PPN
MOVEM T1,.CPEJN## ; AND SAVE IT
MOVE T1,JBTNAM##(J) ;GET ITS PROGRAM NAME
MOVEM T1,.CPEPN## ; AND SAVE IT
MOVE P4,.CPSTT## ;GET THE TRAP CODE
CAIE P4,PF.NXM ;IS IT A NXM?
SKIPA P4,[UE.PEF] ;NO--SET UP PARITY ERROR FLAG
MOVEI P4,UE.NXM ;YES--SET UP NXM FLAG
AOS .CPNPT## ;COUNT TOTAL NUMBER OF PARITY/NXM TRAPS
DMOVE T1,.USPFP ;GET THE PAGE FAIL PC
DMOVEM T1,.CPMDP## ;FOR ERROR IN JOB MESSAGES
DMOVEM T1,.CPPPD## ;STORE TROUBLE PC
TDZ T1,[7777,,-1] ;HOKEY IT UP
IOR T1,T2 ;SINCE A ONE WORD GETTAB
MOVEM T1,.CPPPC## ;SAVE THE PC FOR DAEMON
MOVEM T1,.CPMPP## ;ALSO OLD PLACE
MOVE T2,.USPFW ;GET THE PAGE FAIL WORD
MOVEM T2,.CPPFW## ;SAVE THE PAGE FAIL WORD FOR DAEMON
TRNE P4,UE.NXM ;IS THIS A NXM?
JRST PRTRPC ;YES--THEN THERE'S NO DATA TO PICK UP
WRUBR [SG.LAB+7B11] ;NO--SET PREVIOUS ACS TO BLOCK 7
PXCT PX.MEM,[MOVE T3,0] ;PICK UP BAD DATA WORD FROM BLOCK 7
EXECAC ;RESTORE MONITOR AC SETTINGS
MOVEM T3,.CPTBD## ;SAVE BAD DATA FOR DAEMON
PRTRPC: MOVE T4,[PXCT PX.MEM,[MAP P1,(T2)]] ;SET UP PXCT OF MAP INSTRUCTION
SKIPL .CPPFW## ;IS THIS A USER CONTEXT REFERENCE?
TLZ T4,(PX.MEM,) ;NO--THEN PXCT BECOMES REGULAR XCT
XCT T4 ;DO A MAP TO TURN PF WORD INTO PHYS ADDR IN P1
MOVEM P1,.CPPBA## ;SAVE BAD PHYSICAL ADDR FOR DAEMON
TLZ P1,777760 ;GET RID OF LEFT HALF STUFF
ROT P1,W2PLSH## ;TURN RH OF P1 INTO PAGE NUMBER OF BAD LOC
MOVE T3,.CPMAP## ;GET PAGE NUMBER OF EPMP FOR THIS CPU
PUSH P,.ERPIL/PAGSIZ##(T3)
HRRM P1,.ERPIL/PAGSIZ##(T3)
HRRI P1,(<PM.DCD>B2+PM.WRT+PM.PUB)
HRLM P1,.ERPIL/PAGSIZ##(T3)
CLRPGT (0,.ERPIL) ;CLEAR OUT OLD ENTRY FOR .ERPIL
LSH P1,-^D27 ;TURN P1 INTO WORD NUMBER WITHIN PAGE
ADDI P1,.ERPIL ;AND GET PAGE NUMBER CORRESPONDING TO MAP SLOT
TRNE P4,UE.NXM ;IS THIS A NXM?
SKIPA T1,[[ASCIZ / non-existent memory trap/]] ;YES
MOVEI T1,[ASCIZ / parity trap/] ;NO
PUSHJ P,PRMPC ;ANNOUNCE ERROR
MOVEI T1,[ASCIZ /Page fail word = /]
MOVE T2,.CPPFW##
PUSHJ P,PRMHW ;PRINT THE PAGE FAIL WORD
MOVEI T1,[ASCIZ /Mapped page fail address = /]
MOVE T2,.CPPBA##
PUSHJ P,PRMHW ;PRINT THE MAP WORD (PHYS. ADDRESS)
MOVEI T1,[ASCIZ /Incorrect contents = /]
MOVE T2,.CPTBD##
TRNN P4,UE.NXM ;IF A NXM, NO DATA TO PRINT
PUSHJ P,PRMHW ;PRINT THE BAD DATA
MOVEI T1,[ASCIZ /CONI PI, = /]
MOVE T2,.CPTPI##
PUSHJ P,PRMHW ;PRINT THE CONI PI BITS
SETZ P2, ;CLEAR FLAG REGISTER
;HERE TO START RETRIES
PUSHJ P,PRTRY ;REFERENCE LOCATION
JRST PRHMF ;RETRIES FAILED! HARD MEMORY FAILURE
;HERE WE KNOW WE CAN RECOVER THE USER
MOVEM T1,.CPTGD## ;SAVE THE GOOD DATA FOR ERROR REPORTING
AOS .CPSAR## ;UPDATE COUNTER OF SOFT PARITY ERRORS
;HERE IF RETRIES WERE SUCCESFUL, LOG SOFT ERROR AND DISMISS
TRO P2,PFCPF0 ;INDICATE WE'RE A KS10
HRLM P2,.CPPTR## ;SAVE STATUS FLAGS FOR ERROR REPORTING
HRRM T3,.CPPTR## ;SAVE RETRY COUNT FOR ERROR REPORTING
MOVE T3,.CPMAP## ;GET .EPMP FOR THIS CPU
POP P,.ERPIL/PAGSIZ##(T3)
MOVEI T1,[ASCIZ /Retry successful! Correct contents = /]
MOVE T2,.CPTGD
PUSHJ P,PRMHW ;PRINT SUCCESS AND GOOD DATA
MOVEI T1,EDELIM## ;GET ADDRESS OF TEXT
PUSHJ P,PRMSG ;PRINT END DELIMITER
MOVEI T1,.ERKPT ;ASSUME PARITY CODE FOR DAEMON
TRNE P4,UE.NXM ;IS THIS REALLY A NXM?
MOVEI T1,.ERKSN ;YES--GET NXM CODE
HRL T1,.CPSLF## ;THIS CPU'S CDB ADDRESS
PUSHJ P,DAEDIE## ;PUT THE ENTRY IN THE QUEUE
JRST PTXIT ;EXIT THE TRAP
;LOCAL RETRY ROUTINE
;RETURNS +1 IF RETRIES FAIL
;RETRUNS +2 IF ANY RETRY WINS
; T1/GOOD DATA
; T3/RETRY WHICH SUCCEEDED (FIRST =1)
PRTRY: MOVEI T3,1 ;INIT RETRY COUNTER
MOVEI T2,TRYBAD ;GET TRAP TEST ADDRESS
EXCH T2,.USPFN+1 ;EXCHANGE WITH WHAT'S THERE NOW
PUSH P,.USPFP ;IF A TRAP HAPPENS, HOW WE GOT HERE IS LOST
PUSH P,.USPFP+1 ;SAVE ORIG PC
PRTY1: TRO P2,PFCPF0 ;NOTE THIS IS TEST REFERENCE
WREBR @.CPEBR## ;INVALIDATE CACHE
MOVE T1,0(P1) ;TRY THE REFERENCE
TRZ P2,PFCPF0 ;CLEAR THE REFERENCE FLAG
TRZN P2,PFCPF2 ;ERROR DURING REFERENCE?
JRST PRTY3 ;NO--GIVE A GOOD RETURN
CAIGE T3,TRPTRY ;YES--RETRY COUNT EXHAUSTED?
AOJA T3,PRTY1 ;NO--TRY AGAIN
SKIPA ;YES--GIVE AN ERROR RETURN
PRTY3: AOS -2(P) ;SET FOR SKIP RETURN
POP P,.USPFP+1 ;RESTORE PC
POP P,.USPFP ;RESTORE OLD CONTENTS
EXCH T2,.USPFN+1 ;RESTORE STANDARD TRAP ADDRESS
POPJ P, ;EXIT
;HERE ON TRAPS OCCURING DURING RECOVERY ATTEMPTS
TRYBAD: TRNN P2,PFCPF0 ;ARE WE HERE BECAUSE OF TEST REFERENCE?
STOPCD (.,HALT,UPF) ;++UNEXPECTED PAGE FAIL
LDB T1,[POINT 5,.USPFW,5] ;GET PAGE FAIL CODE
CAIGE T1,PF.PAR ;PARITY OR NXM ERROR?
STOPCD (.,HALT,WPT) ;++WRONG PARITY TRAP
TRO P2,PFCPF2 ;YES--INDICATE ERROR
AOS .USPFP+1 ;GET PC OF TEST REFERENCE
XJRSTF .USPFP ;GO BACK AGAIN
;HERE WHEN RETRIES FROM MEMORY FAIL
PRHMF: SETZM .CPTGD## ;ZERO "GOOD DATA" SINCE WE DIDN'T GET ANY
TRNN P4,UE.NXM ;DON'T DO NEXT IF NXM
SETZM (P1) ;ZERO (AND RE-WRITE) THE ROTTEN LOCATION ALSO
PUSH P,P2 ;SAVE P2
PUSH P,T3 ;SAVE T3
PUSHJ P,PRTRY ;NOW SEE IF IT'S REALLY HARD (MEMORY BROKEN)
TDZA P1,P1 ;IT IS, SET P1 = 0
SETO P1, ;IT'S NOT, SET P1 = -1
POP P,T3 ;RESTORE T3
POP P,P2 ;RESTORE P2
MOVE T1,.CPMAP## ;GET .EPMP FOR THIS CPU
POP P,.ERPIL/PAGSIZ##(T1)
AOS .CPHPT## ;BUMP HARD (AR/ARX) PARITY TRAP COUNT
TRO P2,PFCPF0!PFCPF1;SAY HARD ERROR AND KS10 FOR ERROR REPORTING
HRLM P2,.CPPTR## ;SAVE FLAGS
HRRM T3,.CPPTR## ;SAVE RETRY COUNT FOR ERROR REPORTING
TRNE P4,UE.NXM ;IF THIS IS A NXM, MESSAGE IS DIFFERENT
SKIPA T1,[[ASCIZ /Retry unsuccessful./]]
MOVEI T1,[ASCIZ /Retry unsuccessful. Offending location zeroed./]
PUSHJ P,PRMSG ;ANNOUNCE FAILURE
MOVEI T1,.ERKPT ;ASSUME PARITY CODE FOR DAEMON
TRNE P4,UE.NXM ;IS THIS REALLY A NXM?
MOVEI T1,.ERKSN ;YES--GET NXM CODE
HRL T1,.CPSLF## ;AND CDB ADDRESS
PUSHJ P,DAEDIE## ;CALL DAEMON TO LOG ERROR
MOVE T1,.CPPPC## ;GET THE TRAP PC
TLNE T1,(XC.USR) ;IS THE TRAP FROM USER MODE?
JRST PRHMF1 ;YES--GO KILL USER
HRRZ T1,.CPPFW## ;GET THE PROBLEM ADDRESS
SKIPGE .CPPFW## ;IS THIS A USER CONTEXT REFERENCE?
JRST PRHMF0 ;YES--GO CHECK IF AT SCHED OR PI LEVEL
MOVE T2,SYSLEN## ;NO--GET LENGTH OF MONITOR'S HIGH SEG
ADDI T2,MONORG##-1 ;FORM EVA OF THE TOP OF THE HIGH SEG
CAIL T1,MONORG## ;IS THE ERROR IN THE
CAILE T1,(T2) ; MONITOR'S HIGH SEGMENT?
JRST PRHMF0 ;NO--GO CHECK OTHER THINGS
LSH T1,W2PLSH## ;YES--FORM THE EXEC VIRTUAL PAGE NUMBER
MOVE T2,.CPPBA## ;GET THE MAPPED PHYSICAL ADDRESS
TDZ T2,[777760,,777] ;ONLY WANT BASE ADDRESS OF PAGE
PUSHJ P,PAGRPL## ;TRY TO REPLACE THIS CODE PAGE
JRST PARHLT## ;IT DIDN'T WORK
MOVEI T1,[ASCIZ /Replaced monitor code page from disk./] ;GET TEXT
PUSHJ P,PRMSG ;PRINT IT
MOVEI T1,EDELIM## ;GET END DELIMITER
PUSHJ P,PRMSG ;PRINT IT
PJRST PTXIT ;EXIT THE TRAP
PRHMF0: SETOM .CPREP## ;SET PARITY MSG FLAG IN CASE THIS IS FATAL
TRNE P4,UE.NXM ;IS THIS A NXM?
SETZM .CPREP## ;YES--SET FLAG PROPERLY
SKIPN .CPISF## ;ARE WE IN THE SCHEDULER
CONSZ PI,PI.IPA ; OR ARE WE AT INTERRUPT LEVEL?
JRST PARHLT## ;YES--SORRY BUT WE CAN'T DO A THING
SKIPGE .CPPFW## ;WAS THIS A MONITOR REF TO USER SPACE AT UUO LVL?
JRST PRHMF2 ;YES--TREAT AS USER ERROR
CAIL T1,340000 ;IS THE ERROR IN THE
CAILE T1,377777 ; USER PER PROCESS AREA?
JRST PARHLT## ;NO--IT'S IN THE MONITOR DATA BASE, FATAL!
SETZ P2, ;YES, CALL IT A LOWSEG ERROR
JRST PRHMF3 ;TREAT AS FATAL USER ERROR
PRHMF1: TDNN P4,.CPCN1## ;IS USER ENABLED TO HANDLE THIS HIMSELF?
JRST PRHMF2 ;NO--GO ON
MOVE T2,JBTSTS##(J) ;YES--GET JOB STATUS WORD
TLNE T2,JACCT ;IS JOB PRIVILEGED?
JRST PRHF1A ;YES--TRAP TO HIM
MOVE T2,JBTPPN##(J) ;NO--GET HIS PPN
CAME T2,FFAPPN## ;IS IT THE OPERATOR PPN
CAMN T2,UMDPPN## ; OR THE USER MODE DIAG PPN?
JRST PRHF1A ;YES--LET'S TRAP TO HIM AS REQUESTED
JRST PRHMF2 ;NO--THEN WE IGNORE HIS TRAP REQUEST
PRHF1A: MOVEI T1,EDELIM## ;GET END DELIMITER
PUSHJ P,PRMSG ;PRINT IT
WRPI PI.ON ;TURN PI'S BACK ON
DMOVE T1,.CPPPD## ;GET THE PROBLEM PC
HRRZ T3,P4 ;PUT PARITY/NXM BIT HERE
JRST SAROV3 ;GO TRAP TO USER
PRHMF2: SETZ P2, ;SET FLAG ASSUMING LOW SEG ERROR
MOVE J,.CPJOB## ;GET THE OFFENDING JOB #
SKIPG J,JBTSGN##(J) ;DOES THIS JOB HAVE A HIGH SEG?
JRST PRHMF3 ;NO--GO ON
HRRZ T1,.CPPFW## ;GET THE PROBLEM ADDRESS
CAML T1,.USHSS ;IS ADDRESS IN THE USER HIGH SEGMENT?
CAMLE T1,.USHSE
JRST PRHMF3 ;NO--GO ON
SETO P2, ;YES--SET FLAG INDICATING HIGH SEG ERROR
PUSHJ P,HGHPAR## ;GO PROCESS OTHER JOBS USING THIS SEGMENT
PRHMF3: JUMPN P1,PRHMF4 ;IF MEMORY IS OK, DON'T MARK OUT PAGE
LDB T1,[POINT 13,.CPPBA##,26] ;GET THE PAGE NUMBER TO MARK OFF-LINE
PUSH P,T1 ;SAVE PAGE NUMBER
IDIVI T1,^D36 ;COMPUTE NXMTAB INDEX AND BITTBL INDEX
MOVE T2,BITTBL##(T2) ;GET CORRECT BIT TO SET
IORM T2,NXMTAB##(T1) ;MARK OUT PAGE IN NXMTAB
MOVEI T1,[ASCIZ /Location still bad after zeroing.
Setting off-line physical page /] ;GET TEXT
POP P,T2 ; AND PAGE NUMBER
PUSHJ P,PRMOC ;TELL HIM WHAT WE DID
MOVE T1,[.CSCPO,,.ERCSC]
PUSHJ P,DAEDIE## ;LOG CONFIGURATION CHANGE
PRHMF4: MOVEI T1,EDELIM## ;GET END DELIMITER
PUSHJ P,PRMSG ;PRINT IT
MOVE J,.CPJOB## ;GET JOB NUMBER
JUMPE P2,PRHMF5 ;GO STOP THIS JOB IF LOW SEG ERROR
MOVEI T1,JS.MPE ;DID HGHPAR SAY THAT THIS JOB
TDNE T1,JBTSTS##(J) ; COULDN'T BE SAVED?
JRST PRHMF5 ;YES--JUST GO STOP IT
WRPI PI.ON ;NO--TURN PI'S BACK ON
HLLZ T1,.CPMPS## ;GET CPU REQUESTS MEMORY SCAN BITS
HRRI T1,(P4) ;SET PARITY OR NXM BIT
IORM T1,.CPAEF## ;SET REQUEST
MOVE P,[XWD MJOBPD##,.JDAT+JOBPDL##] ;DUMMY STACK FOR WSCHED
PUSH P,.USPFP ;STACK RETURN USER ADDRESS FOR WSCHED
PUSH P,.USPFP+1 ;SECOND HALF AS WELL
PJRST WSCHED## ;RESCHEDULE THIS JOB TO RE-RUN WITH NEW HIGH SEG
PRHMF5: MOVSI T1,JACCT ;CLEAR JACCT SO DAMAGED PROGRAM
ANDCAM T1,JBTSTS##(J) ; WON'T HAVE PRIVILEGES
MOVEI T1,JS.MPE ;ASSUME PARITY ERROR IN JOB
TRNE P4,UE.NXM ;IS IT A NXM?
MOVEI T1,JS.NXM ;YES--GET NXM IN JOB STATE BIT
IORM T1,JBTSTS##(J) ;SET IN JOB STATUS WORD
HLLZ T1,.CPMPS## ;GET CPU REQUESTS MEMORY SCAN BITS
HRRI T1,(P4) ;SET PARITY OR NXM BIT
IORM T1,.CPAEF## ;SET REQUEST FOR PI 7
SETOM .CPSCF## ;FORCE RESCHEDULE
SETOM .CPCKF## ;SET FLAG FOR PI 7 INTERRUPT
WRPI XI.RQC## ;REQUEST PI 7
WRPI PI.ON ;ALLOW INTERRUPTS NOW (MAINLY PI 7)
PJRST ESTOP## ;GO STOP THIS JOB
;HERE ON TRAP DURING PARITY SWEEP
SWTRP: EXCH T1,.CPSTT## ;RESTORE T1, SAVE TRAP CODE
PUSH P,T1 ;SAVE T1
HRRZ T1,.USPFP+1 ;GET PC OF TRAP
CAIE T1,CPSMPI ;BETTER MATCH THE SWEEP BLT ADDRESS
STOPCD (.,HALT,NPI) ;++NOT PARITY INSTRUCTION
MOVE T1,.USPFW ;GET THE PAGE FAIL WORD
MOVEM T1,.CPPFW## ;AND SAVE IT
WRUBR [SG.LAB+07B11] ;SET PREVIOUS AC BLOCK TO 7
PXCT PX.MEM,[MOVE T1,0] ;GET BAD DATA WORD FOR DAEMON
EXECAC ;RESTORE MONITOR'S AC BLOCK
MOVEM T1,.CPTBD## ;SAVE BAD DATA
SETOM .CPPTH## ;INDICATE ERROR ON SWEEP
MOVEI T1,3 ;BUMP RETURN PC BY 3 TO
ADDM T1,.USPFP+1 ; INDICATE A TRAP HAPPENED
POP P,T1 ;RESTORE T1
JRST PTXIT1 ;EXIT BACK TO SWEEP ROUTINE
;ROUTINE TO PRINT A MESSAGE PREFIXED BY "CPUx" AND
;FOLLOWED BY "AT EXEC(USER) PC XXXXXX"
; T1=MESSAGE ADDRESS
PRMPC: PUSHJ P,SAVE1## ;SAVE P1 TO REMEMBER ADDRESS OF MESSAGE
MOVE P1,T1 ;SAVE
PUSH P,.CPTOA## ;SAVE COMMAND OUTPUT ADDRESS
MOVEI T2,CTYWAT## ;GET ONE THAT DOESN'T USE PI SYS
MOVEM T2,.CPTOA##
MOVEI T1,SDELIM## ;GET ADDRESS OF TEXT
PUSHJ P,CONMES## ;PRINT START DELIMITER
MOVE T2,.CPLOG## ;GET THIS CPU'S NAME
PUSHJ P,PRNAME## ;PRINT IT
MOVE T1,P1 ;GET ADDRESS OF MESSAGE IN T1
PUSHJ P,CONMES## ;PRINT MESSAGE
MOVE T2,.CPPPC## ;GET SAVED PC
PUSHJ P,PCP## ;PRINT "AT EXEC/USER XXXXXX"
MOVEI T1,[ASCIZ / on /] ;SEPARATE FROM DATE/TIME
PUSHJ P,CONMES## ;PRINT IT
PUSHJ P,DAYTIM## ;PRINT DATE AND TIME
MOVEI T1,[ASCIZ /Job/];TELL THEM WHO WAS RUNNING
PUSHJ P,CONMES## ;PRINT "JOB"
PUSHJ P,PRJBNM## ;PRINT JOB INFO
MOVEI T1,[ASCIZ / was running
/]
PUSHJ P,CONMES## ;PRINT "WAS RUNNING"
PRMPC2: POP P,.CPTOA## ;RESTORE SCNSER ADDRESS
POPJ P, ;RETURN
;ROUTINES TO PRINT A MESSAGE FOLLOWED BY NUMBER IN HALFWORD OR OCTAL FORMAT
; T1=MESSAGE ADDRESS, T2=NUMBER
PRMOC: PUSHJ P,SAVE3## ;SAVE P1-P3
MOVEI P3,OCTPNT## ;GET ADDRESS OF OCTAL PRINT ROUTINE
JRST PRMHW1 ;GO TO COMMON CODE
PRMHW: PUSHJ P,SAVE3## ;SAVE P1-P3
MOVEI P3,HWDPNT## ;GET ADDRESS OF HALFWORD PRINT ROUTINE
PRMHW1: MOVE P1,T1 ;SAVE
MOVE P2,T2 ;SAVE
PUSH P,.CPTOA## ;SAVE COMMAND OUTPUT ADDRESS
MOVEI T2,CTYWAT## ;GET ONE THAT DOESN'T USE PI SYS
MOVEM T2,.CPTOA##
MOVE T1,P1 ;GET ADDRESS OF MESSAGE IN T1
PUSHJ P,CONMES## ;PRINT MESSAGE
MOVE T1,P2 ;GET NUMBER TO PRINT (IF ANY)
PUSHJ P,(P3) ;PRINT NUMBER IN DESIRED FORMAT
PUSHJ P,CRLF## ;END WITH CRLF
PJRST PRMPC2 ;FINISH UP
;ROUTINE TO PRINT A MESSAGE
; T1=MESSAGE ADDRESS
PRMSG: PUSHJ P,SAVE2## ;SAVE P1,P2 TO REMEMBER ADDRESS OF MESSAGE
MOVE P1,T1 ;SAVE
PUSH P,.CPTOA## ;SAVE COMMAND OUTPUT ADDRESS
MOVEI T2,CTYWAT## ;GET ONE THAT DOESN'T USE PI SYS
MOVEM T2,.CPTOA##
MOVE T1,P1 ;GET ADDRESS OF MESSAGE IN T1
PUSHJ P,CONMES## ;PRINT MESSAGE
PUSHJ P,CRLF## ;END WITH CRLF
PJRST PRMPC2 ;FINISH UP
;HERE ON PAGE TABLE PARITY TRAP (PF CODE 25)
PTPAR: WREBR @.CPEBR## ;CLEAR THE PAGE TABLE
AOS .CPPTP## ;COUNT A PAGE TABLE PARITY ERROR
MOVE T1,.CPSTT## ;RESTORE T1
MOVEM T1,.CPA17## ;SAVE 17
MOVEI 17,.CPA00## ;MAKE BLT POINTER
BLT 17,.CPA17##-1 ;SAVE ACS IN CPU DATA BLOCK
MOVE P,.CPEPD## ;SET UP ERROR STACK
SKIPGE T1,.CPPTF## ;PICK UP COUNT OF PAGE TABLE FAILURES
MOVEI T1,^D10 ;NONE YET, INITIALIZE
SOSG T1 ;IF COUNT HASN'T EXPIRED, JUST RETRY.
; COUNTER IS RESET ON EVERY CLOCK TICK.
STOPCD .,HALT,PTP, ;++PAGE TABLE PARITY
MOVEM T1,.CPPTF## ;REMEMBER COUNTER
DMOVE T1,.USPFP ;GET PAGE FAIL PC
DMOVEM T1,.CPPPD## ;SAVE FOR PRINT ROUTINE
MOVE J,.CPJOB## ;SET UP J WITH CURRENTLY RUNNING JOB
MOVEI T1,[ASCIZ / page table parity trap/]
PUSHJ P,PRMPC ;ANNOUNCE ERROR
MOVEI T1,[ASCIZ /Page fail word = /]
MOVE T2,.USPFW
PUSHJ P,PRMHW ;PRINT THE PAGE FAIL WORD
MOVEI T1,[ASCIZ /CONI PI, = /]
MOVE T2,.CPTPI##
PUSHJ P,PRMHW ;PRINT THE CONI PI BITS
MOVEI T1,EDELIM## ;GET ADDRESS OF TEXT
PUSHJ P,PRMSG ;PRINT END DELIMITER
PTXIT: MOVSI 17,.CPA00## ;BLT POINTER TO RESTORE ACS
BLT 17,16 ;RESTORE ACS
MOVE 17,.CPA17## ;AC 17 ALSO
PTXIT1: WRUBR .CPTCX## ;RESTORE THE CONTEXT AT TIME OF TRAP
EXCH T1,.CPTPI## ;GET PI'S AT TRAP ENTRY, SAVE T1
TRNE T1,PI.ON ;WERE THE PI'S ON?
WRPI PI.ON ;YES--TURN PI'S BACK ON
EXCH T1,.CPTPI## ;RESTORE T1
XJRSTF .USPFP
;HERE TO HANDLE A PAGE FAULT
SEILMA: MOVE T1,.CPSTT## ;RESTORE T1
WRPI PI.ON ;RESTORE THE PI SYSTEM
SKIPN .CPEJ1## ;SKIP NEXT IF EXEC PAGE FAULT IN PROGRESS
DMOVEM T1,.CPST1## ;SAVE T1 AND T2 IN CASE OF CRASH
DMOVE T1,.USPFP ;GET THE PAGE FAIL PC
DMOVEM T1,.CPAPC## ;STORE IT AS POTENTIAL ERROR PC
DMOVEM T1,.USMUP ;STORE WHERE KI WOULD PUT IT
HRR T1,T2 ;GET PC INTO T1 AS A ONE WORD PC
MOVE T2,.USPFW ;GET THE USER PAGE FAIL WORD
MOVEM T2,.CPPFW## ;SAVE PAGE FAULT WORD FOR CRASH
; DPB T2,[POINT 18,T2,32] ;SHIFT VIRTUAL ADDRESS OVER 3 PLACES
; ROT T2,6 ;PLACE PAGE FAIL CODE AND VIRTUAL ADDRESS
; ;WHERE IT WAS ON KI10
; TRZE T2,40 ;USER BIT ON?
;; TLO T2,(1B8) ;YES, SET IT WHERE KI10 USER BIT WAS
; ;WE NOW HAVE KI10 STYLE PAGE FAIL WORD.
; AND T2,[1777,,37] ;CLEAR UNUSED BITS
; TLNE T2,(1B8) ;USER REF?
; TRNN T2,10 ;YES, ACCESS ALLOWED OFF?
; JRST SEILMB ;NOT USER REF OR ACCESS ALLOWED OFF
; TRNN T2,4 ;USER REF, ACCESS ALLOWED ON. WRITE OFF?
; TRO T2,1 ;YES, DEDUCE THAT HE TRIED TO WRITE
SEILMB: TLNE T1,(XC.USR) ;PAGE FAULT IN EXEC MODE?
JRST SEILM0 ;NO, PROCEED
JRST SEILM7 ;YES--EXEC ILL MEM REF, CHECK FOR ERJMP
SEILM0: MOVE P,[XWD MJOBPD##,.JDAT+JOBPDL##] ;SETUP A PUSH DOWN LIST
SKIPN .USJOB
STOPCD .,CPU,PFN ;++PAGE FAULT IN NULL JOB
PUSH P,T1 ;SAVE USER'S PC
MOVE T3,T2 ;FAULT WAS IN USER MODE, SAVE PFC FOR
; POSSIBLE CALL TO USRFLT
LDB T2,[POINT 5,T2,5] ;CLEAR ALL BUT THE PAGE FAIL CODE
MOVE T4,.JDAT+JOBENB## ;GET APR ENABLE BITS
TRNE T4,AP.ILM ;IS USER ENABLED?
JRST SUILM ;YES--DO SUILM INSTEAD
MOVE T4,T1 ;PC WORD INTO T4 FOR USRFLT
DMOVE T1,.USPFP ;GET DOUBLE WORD PC
PUSHJ P,USRFLT## ;SEE IF PAGE FAULT FOR A VM USER
; WILL NOT RETURN IF SO (DISPATCH TO USER)
HRRI T1,AP.ILM ;COULDN'T HANDLE IT - USER GETS ILL MEM REF
JRST SEPDL1 ;GO SAY "ILL. MEM. REF."
;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,<
JUMPG T2,SEJL2A ;JUMP IF NOT USER REF
PUSHJ P,INTLVL## ;YES, AT UUO LEVEL?
PUSHJ P,[PUSHJ P,SAVT## ;YES
MOVE T1,.CPPFW## ;GET PAGE FAULT WORD
LSH T1,W2PLSH## ;PAGE NUMBER
ANDI T1,HLGPGS
PUSHJ P,TSSPT## ;A SPY PAGE?
POPJ P, ;NO
PJRST UADERR##] ;YES,BLAME THE USER
SEJL2A:>
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,<ERJMP>_-^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.
HLLZS .CPAPC## ;CLEAR JUNK IN RIGHT HALF OF FLAGS WORD (PCS)
MOVEM T1,.CPAPC##+1 ;SET CONTINUATION ADDRESS
MOVE T1,.CPST1## ;RESTORE T1 AGAIN
SETZM .CPEJ1## ;CLEAR NESTING FLAG
WRUBR .CPTCX## ;RESTORE TRAP CONTEXT
XJRSTF .CPAPC## ;....
;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,.USPFP ;ALSO MAKE UPMP LOOK RIGHT
MOVEM T2,.CPPFW## ;SET TRUE PAGE FAULT WORD
MOVEM T2,.USPFW ;ALSO MAKE UPMP LOOK RIGHT
SEILME: SETZM .CPEJ1## ;CLEAR NESTING FLAG
STOPCD .+1,JOB,IME,DIEIME ;++ILL MEM REF FROM EXEC
DMOVE T1,.CPST1## ;AND THE TEMP ACS USED
JRSTF @.CPAPC## ;RETURN
DIEIME: PUSHJ P,INLMES## ;ADD SOME TEXT
ASCIZ /Page fail word = /
MOVE T1,.USPFW ;GET PAGE FAIL WORD
PJRST HWDPNT## ;PRINT AS HALF-WORDS AND RETURN
;HERE FROM SEILM IF PAGE FAULT IS IN USER MODE AND APRENB DONE
; T1=USER PC AND T3=PAGE FAULT WORD
;T3=PAGE FAULT WORD
SUILMX::
DMOVE T1,.USMUO ;GET PC FROM "UUO"
JRST SUILM1
SUILM:: DMOVE T1,.USPFP ;GET DOUBLE WORD PC
SUILM1: MOVE R,.CPADR## ;GET THE ADDRESS OF THE USER'S JOB DATA AREA
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::
DMOVE T1,.USMUO ;GET FLAGS & PC
MOVEI T3,AP.POV ;SET POV BIT FOR USER
JRST SAROV3 ;FINISH UP
;ONCE A SECOND TASKS FOR KS10'S
KSSEC::
;HERE ONCE A SECOND TO BE SURE UBA'S DIDN'T LOSE ASSIGNMENTS
MOVEI T2,UBA1PI## ;PI'S FOR UBA #1
MOVEI T1,UNBSTW ;UBA STATUS REGISTER ADDRESS
HRLI T1,1 ;DO UBA #1
PUSHJ P,UBACHK ;CHECK IT
MOVEI T2,UBA3PI## ;PI'S FOR UBA #3
HRLI T1,3 ;DO UBA #3
PUSHJ P,UBACHK ;CHECK IT
;HERE ONCE/SECOND TO COUNT THE KEEP ALIVE COUNTER FOR THE 8080 FRONT END
LDB T1,BKPALV ;GET THE CURRENT COUNT
AOS T1 ;INCREMENT IT
CAILE T1,377 ;WE COUNT IT MODULO 8-BITS
SETZ T1,
DPB T1,BKPALV ;PUT IT IN ITS PROPER PLACE
POPJ P, ;RETURN
BKPALV: POINT 8,RLWORD,27 ;BYTE POINTER TO KEEP ALIVE COUNT
UBACHK: PUSHJ P,UBGOOD ;IS UBA ALIVE?
POPJ P, ;NO--THEN DON'T TRY TO ACCESS IT
RDIO T3,(T1) ;YES--GET UBA STATUS
ANDI T3,UNBDTR!77 ;MASK OFF EXTRA BITS
IORI T2,UNBDTR ;SET DISABLE XFER BIT FOR COMPARE/SET
CAMN T3,T2 ;ARE ALL THE BITS RIGHT ?
POPJ P, ;ALL OK
STOPCD (.+1,DEBUG,ULP) ;++UBA LOST ITS PI ASSIGNMENT
WRIO T2,(T1) ;REASSIGN LEVELS
POPJ P,
SUBTTL DTESER SIMULATION
;ROUTINES TO TURN KEEP ALIVE FUNCTION ON AND OFF WITH 8080 FRONT END
$LOW
SVPPC:: PUSH P,T1 ;SAVE T1
MOVSI T1,(KPACT) ;KEEP ALIVE ACTIVE BIT
TDNN T1,RLWORD ;ARE WE GOING TO GET KAF'ED?
JRST DISKA1 ;NO, JUST BE A LONG NO-OP
ANDCAM T1,RLWORD ;YES, CLEAR THE BIT
MOVE T1,(P) ;RESTORE T1
ADJSP P,-2 ;BALANCE STACK
PUSHJ P,@1(P) ;CALL OUR CALLER
JRST ENAKAL ;PROPAGATE NON-SKIP
AOS (P) ;AND SKIP
;FALL INTO ENAKAL
ENAKAL::PUSH P,T1 ;SAVE T1
MOVSI T1,(KPACT) ;KEEP ALIVE ACTIVE BIT
IORM T1,RLWORD ;SET IT
PJRST DISKA1 ;RETURN
DISKAL::PUSH P,T1 ;SAVE T1
MOVSI T1,(KPACT) ;KEEP ALIVE ACTIVE BIT
ANDCAM T1,RLWORD ;CLEAR IT
DISKA1: POP P,T1 ;CAN'T USE TPOPJ SINCE
POPJ P, ; WE MAY NOT BE MAPPED
$HIGH
;ROUTINE TO GET DATE AND TIME FROM THE FRONT END
;
;IN OUR CASE, THIS (MIGHT BE) A TCU150 ON THE UNIBUS
SPCGDT::MOVE T1,[EXP CLKCSR] ;GET IO ADDRESS OF CSR
PUSHJ P,UBGOOD ;SEE IF INSTALLED
POPJ P, ;NOT INSTALLED, CAN'T HELP
MOVE T1,[EXP CLKCSR] ;RESTORE IO ADDRESS
RDIO T2,0(T1) ;GET DATE
RDIO T3,2(T1) ;GET TIME
HRL T2,T3 ;SAVE TIME,,DATE
RDIO T3,4(T1) ;GET SECOND
LDB T1,[POINT 7,T2,26] ;GET YEARS SINCE 1900
ADDI T1,^D1900 ;MAKE INTO REAL YEAR
CAIGE T1,^D1964 ;BASIC SANITY CHECK
POPJ P, ;CLOCK IS BAD
MOVEM T1,LOCYER## ;SAVE YEAR
LDB T1,[POINT 4,T2,30] ;GET MONTH
SKIPE T1 ;SANE?
CAILE T1,^D12 ;...
POPJ P, ;NO
MOVEM T1,LOCMON## ;YES, SAVE MONTH
SOJ T1, ;MAKE INTO TABLE OFFSET
LDB T4,PMONTB## ;GET DAYS IN MONTH - 1
AOJ T4, ;MAKE ONE-BASED
SOJN T1,SPGDT1 ;IF FEBRUARY
MOVE T1,LOCYER## ;GET YEAR
TRNN T1,3 ;AND IF LEAP YEAR
AOJ T4, ;ALLOW FOR EXTRA DAY
SPGDT1: LDB T1,[POINT 5,T2,35] ;GET DAY OF MONTY
SKIPE T1 ;CHECK FOR SANITY
CAMLE T1,T4 ;...
POPJ P, ;BAD CLOCK
MOVEM T1,LOCDAY## ;SAVE DAY OF MONTH
LDB T1,[POINT 5,T2,9] ;GET HOUR
CAILE T1,^D24 ;SEE IF MAKES SENSE
POPJ P, ;SIGH
CAIN T1,^D24 ;MIDNIGHT?
SETZ T1, ;YES, USE OUR CONVENTION
MOVEM T1,LOCHOR## ;SAVE HOUR
LDB T1,[POINT 6,T2,17] ;GET MINUTE
CAILE T1,^D59 ;MAKE SURE IT'S NOT JUNK
POPJ P, ;PARANOIA 1, CLOCK 0
MOVEM T1,LOCMIN## ;SET MINUTE
LDB T1,[POINT 6,T3,35] ;GET SECOND
CAILE T1,^D59 ;FINAL CHECK
POPJ P, ;FAILED
MOVEM T1,LOCSEC## ;SET SECOND AND VALID FLAG
JRST CPOPJ1## ;SUCCESS
;ROUTINE TO SET HARDWARE AND SOFTWARE RELOCATION INFORMATION FOR CURRENT USER
;CALLING SEQUENCE:
; PUSHJ P,SETREL
; ... RETURN HERE
;J = CURRENT JOB NUMBER
;R = PROTECTION,,RELOCATION FOR THE LOW SEGMENT
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 R,JBTADR##(J) ;R = XWD PROTECTION,,EXEC VIRTUAL ADDRESS
; OF THE FIRST PAGE OF THE LOW SEGMENT
MOVEM R,.CPADR## ;SET .CPADR FOR QUICK ACCESS AT APR LEVEL
HLRZM R,.CPREL## ;SET .CPREL FOR ADDRESS CHECKING
IFN FTTRPSET,<
SKIPE T1,.CPSTS## ;HAS TIMESHARING BEEN STOPPED VIA TRPSET
CAIE T1,(J) ;YES, IS IT THIS JOB?
JUMPN T1,SETRLZ ;NO, DON'T CHANGE THE UBR
>
SKIPE J ;NULL JOB ALWAYS HAS A UPMP
JUMPE R,SETRLZ ;THERE IS NO UPMP IF THE JOB HAS NO CORE
HRRZ T1,JBTUPM##(J) ;PAGE NUMBER OF THE CURRENT JOB'S UPMP
JUMPE T1,SETRL2 ;DON'T CHANGE ANYTHING IF THERE ISN'T ONE
HRLI T1,(SG.LUB) ;SET THE LOAD BIT
IFN FTRTTRP,<
MOVEM T1,.CPDTO## ;SAVE FOR RTTRP INTERRUPT LEVEL USE
>
CONO PI,PI.OFF ;MAKE CHANGING ADDRESSABILITY ATOMIC
HRRM T1,@.CPSPT##
WRUBR T1 ;SETUP THE UBR
CONO PI,PI.ON ;CONTEXT SWITCH NOW DONE
JUMPE R,SETRLZ ;DONE IF NULL JOB
HLRZM R,.USHVA ;SET .USHVA FOR ADDRESS CHECKING AT IRP LEVEL
SKIPN T1,.USREL ;HOLEY PROGRAM?
HLR T1,R
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 ;FORCING THE MAP TO BE REDONE?
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 ;INDICATE MAP HAS BEEN REDONE NOW
ANDCAM T1,JBTSGN##(J)
SETRLZ: MOVE T3,JBTPDB##+0 ;NULL JOB PDB
PUSHJ P,FNDPDS## ;SET UP W
SETRL2: SKIPN R,JBTADR##(J) ;RESTORE R - 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 THE 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
CONO PI,PI.OFF ;NO INTERRUPTS WHILE CHANGING UBR/SPT
SKIPE T1 ;IF NOT ZERO,
HRRM T1,@.CPSPT## ; SETUP NEW SPT
TLO T1,(SG.LUB) ;REQUEST LOADING OF UBR
TRNE T1,17777 ;IS THERE A UPMP
WRUBR T1 ;SET FOR CURRENT USER AND CLEAR THE AM
CONO PI,PI.ON ;BOTH THE SPT AND UBR HAVE BEEN CHANGED
JRST TPOPJ## ;RESTORE T1 AND RETURN
SUBTTL MONITOR CONTEXT SUPPORT ROUTINES
REPEAT 0,<
;COROUTINE TO CONTINUE A SUBROUTINE WITH DECNET CONTEXT SET UP AS
;PREVIOUS CONTEXT USER.
;
;ASSUMES CALLER IS IN REGULAR CONTEXT
SVEUD:: EXCH J,(P) ;SAVE J, GET CALLER'S PC
PUSH P,J ;SAVE CALLER'S PC
;ASSUME SOME JOB IS ADDRESSABLE
MOVE J,.UPMP+SECTAB+0 ;GET CURRENT SECTION POINTER
EXCH J,-1(P) ;GET J BACK, SAVE SECTION POINTER
CONO PI,PI.OFF ;MAKE SURE NO ONE GETS CONFUSED BY THIS
PUSH P,.E0DMP## ;SECTION POINTER TO DECNET CONTEXT
POP P,.UPMP+SECTAB+0 ;MAKE IT THE USER MAP
WREBR @.CPEBR## ;FLUSH PAGE TABLE
ADJSP P,-1 ;GET CALLER'S PC OFF STACK
PUSHJ P,@1(P) ;CALL CALLER
CAIA
AOS -1(P) ;CALLER SKIPPED
POP P,.UPMP+SECTAB+0 ;RESTORE UPMP
WREBR @.CPEBR## ;FLUSH PAGE TABLE
JRST ONPOPJ## ;RESTORE PI SYSTEM AND RETURN
IFN FTMP,<PRINTX ?MUST FIX .E0RMP/.E0DMP REFERENCES>
;COROUTINE TO CALL A SUBROUTINE IN REGULAR CONTEXT
;AND RESTORE ORIGINAL CONTEXT ON RETURN
;
;CALLED BY RGCALL MACRO
RGXCAL::PUSH P,.E0RMP## ;GET SECTION 0 POINTER FOR NORMAL CONTEXT
SKIPA ;AND FALL INTO DNXCAL
;COROUTINE TO CALL A SUBROUTINE IN DECNET CONTEXT
;AND RESTORE ORIGINAL CONTEXT ON RETURN
;
;CALLED BY DNCALL MACRO
DNXCAL::PUSH P,.E0DMP## ;GET SECTION 0 POINTER FOR DECNET CONTEXT
EXCH T1,(P) ;SAVE T1, GET NEW CONTEXT
PUSH P,T1 ;SAVE NEW CONTEXT MAPPING
MOVE T1,.CPEPT## ;ADDRESS OF THE EPT
MOVE T1,SECTAB+0(T1) ;GET CURRENT CONTEXT
EXCH T1,(P) ;SAVE CURRENT CONTEXT, GET NEW CONTEXT
PUSH P,T1 ;SAVE NEW CONTEXT MAPPING
HRRZ T1,-3(P) ;GET THE PC FROM THE CALL
HRRZ T1,-1(T1) ;GET THE RH OF THE XCT INSTR
MOVEI T1,@1(T1) ;GET THE EFFECTIVE ADDRESS OF THE JUMP
EXCH T1,0(P) ;RESTORE NEW CONTEXT, SAVE WHERE TO GO
DNXCL1: PUSHJ P,ETRMAP ;SET UP NEW CONTEXT
MOVE T1,-2(P) ;GET BACK ORIGINAL CONTENTS OF T1
PUSHJ P,@0(P) ;CALL THE DESIGNATED ROUTINE
SKIPA ;PROPOGATE NON-SKIP RETURN
AOS -3(P) ;PROPOGATE SKIP RETURN
MOVEM T1,-2(P) ;STORE UPDATED CONTENTS OF T1
ADJSP P,-1 ;CLEAN STACK
POP P,T1 ;RESTORE ORIGINAL CONTEXT
PUSHJ P,ETRMAP ;...
POP P,T1 ;RESTORE T1
POPJ P, ;AND RETURN
;CALL DNMAP TO MAKE DECNET BUFFERS ADDRESSABLE,
;RGMAP TO MAKE USUAL ADDRESS SPACE ADDRESSABLE. ALL ACS ARE PRESERVED.
RGPJ1:: AOS (P) ;SKIP RETURN
RGMAP:: PUSH P,T1 ;SAVE T1
MOVE T1,.E0RMP## ;GET SECTION 0 POINTER FOR NORMAL CONTEXT
JRST ETRMP1 ;FALL INTO ETRMAP
DNPJ1:: AOS (P) ;SKIP RETURN
DNMAP:: PUSH P,T1 ;SAVE T1
MOVE T1,.E0DMP## ;GET SECTION 0 POINTER FOR DECNET CONTEXT
JRST ETRMP1 ;FALL INTO ETRMAP
ETRMAP::
PUSH P,T1 ;WE ADVERTISE THAT ALL ACS ARE PRESERVED
ETRMP1: PUSH P,T2 ;...
MOVE T2,.CPEPT## ;ADDRESS OF THE EPT
CAMN T1,SECTAB+0(T2) ;SETTING UP DIFFERENT CONTEXT?
JRST TTPOPJ## ;NO, RESTORE ACS AND RETURN
RDPI ETRSPI ;SAVE THE PI SYSTEM STATE
WRPI PI.TFP+177 ;PREVENT INTERRUPTS WHILE CHANGING EBR & SECTAB
MOVEM T1,SECTAB+0(T2) ;STORE NEW SECTION 0 POINTER
ANDI T1,17777 ;ISOLATE PAGE NUMBER OF THE NEW MAP
LSH T1,P2WLSH## ;CONVERT TO ADDRESS
MOVEM T1,.CPMAP## ;ADDRESS OF CURRENT SECTION 0 MAP
CONO PAG,@.CPEBR## ;SO THE PAGING MEMORY SEES THE CHANGE
MOVE T1,ETRSPI ;GET SAVED PI STATE
ANDI T1,177 ;KEEP JUST CHANNELS WHICH WERE ON
WRPI PI.TNP(T1) ;TURN THEM BACK ON
JRST TTPOPJ## ;RESTORE TEMPS AND RETURN
$LOW
ETRSPI: BLOCK 1 ;SAVE PI STATE
$HIGH
;COROUTINE TO ENTER DECNET CONTEXT FOR THIS SUBROUTINE (IF NOT THERE ALREADY)
;AND RETURN TO REGULAR CONTEXT ON EXIT. NO-OP IF ALREADY IN DECNET CONTEXT
SVDCN:: PUSH P,T1 ;SAVE T1
MOVE T1,.CPEPT## ;GET EPT FOR THIS CPU
MOVE T1,SECTAB+0(T1) ;GET S0 POINTER
CAMN T1,.E0DMP## ;IS IT DECNET?
JRST TPOPJ## ;YES, DON'T DO ANYTHING
EXCH T1,(P) ;SAVE CURRENT CONTEXT, GET BACK T1
EXCH T1,-1(P) ;SAVE T1, GET RETURN PC
PUSH P,T1 ;SAVE RETURN PC
MOVE T1,.E0DMP## ;GET DECNET CONTEXT MAPPING
PJRST DNXCL1 ;CALL OUR CALLER AND RETURN
>;END REPEAT 0
SUBTTL IOCSS - I/O SERVICE SUBROUTINES (UUOCON AND DEVICE ROUTINES)
;HERE TO CHECK FOR EXISTENCE OF UBA DEVICES
; CALL MOVE T1,<ADR> OF DEVICE TO CHECK
; PUSHJ P,UBGOOD
; LOSE RETURN
; WIN RETURN
UBGOOD::PUSHJ P,SAVT## ;RESPECT T REGS
SETZ T2, ;BITS FOR TIOE
MOVE T3,[EXP UBNOGD] ;TEMP PAGE FAIL TRAP ADDR
RDPI T4 ;SAVE STATE OF PI'S
WRPI PI.OFF ;DISABLE INTERRUPTS
EXCH T3,.USPFN+1 ;SET TEMPORARY PAGE FAIL TRAP ADR
TIOE T2,(T1) ;CHECK FOR DEVICE
SKIPA ;FAILED
AOS (P) ;WIN
MOVEI T2,UNBNED!UNBTMO ;CLEAR NED IN UNIBUS ADAPTER
HRRI T1,UNBSTW ;GET BASIC ADDRESS OF UNIBUS
BSIO T2,(T1) ;CLEAR FLAGS
MOVEM T3,.USPFN+1 ;RESTORE TRAP VECTOR
TRNE T4,PI.ON ;WERE PI'S ON?
WRPI PI.ON ;YES--THEN ENABLE THEM
POPJ P, ;RETURN
;HERE WHEN ADDRESS IS BUM
UBNOGD: AOS .USPFP+1 ;SKIP LOSING INSTRUCTION
JRST @.USPFP+1 ;JUST RETURN(NONSKIP)
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
IFE FTXMON,<
SPCSF:: ;THE KS DOESN'T DO EXTENDED ADDRESSING, YET
>
SVEUF::
PUSH P,@.CPSPT##
PUSH P,T1 ;SAVE A TEMPORARY
RDUBR T1 ;GET THE USER 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
IFE FTXMON,<
SPCSB:: ;SET PCS FROM DEVISN
>
SVEUB:: PUSH P,@.CPSPT##
PUSH P,T1 ;SAVE A TEMPORARY
RDUBR 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,@.CPSPT##
PUSH P,T1 ;SAVE A TEMPORARY
RDUBR T1 ;GET THE CONTENTS OF THE USER AND EXEC BASE REGISTERS
SSEU1: EXCH T1,-2(P) ;GET THE CALLER'S PC AND SAVE THE CONTENTS
; OF THE UBR AND EBR
EXCH T1,0(P) ;SAVE THE CALLER'S PC IN A TEMPORARY LOCATION
; ON THE STACK AND RESTORE T1
PUSHJ P,@0(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 -3(P) ;CPOPJ1 RETURN - BUMP RETURN PC
ADJSP P,-1 ;TOSS CALLER'S PC
CONO PI,PI.OFF ;DON'T ALLOW INTERRUPTS UNTIL UBR/SPT AGREE
POP P,@.CPSPT##
EXCH T1,0(P) ;GET THE PREVIOUS CONTENTS OF THE UBR(&SAVE T1)
RDUBR 1(P) ;GET PRESENT UBR
CAMN T1,1(P) ;GOING TO CHANGE IT TO WHAT IT IS?
JRST SSEU2 ;YES, DON'T CLEAR THE PAGING MEMORY
WRUBR T1 ;RESTORE THE UBR
SSEU2: CONO PI,PI.ON ;SAFE TO ALLOW INTERRUPTS
JRST TPOPJ## ;AND RETURN
;ROUTINE TO SET UP UNIBUS ADAPTER MAPPING REGISTERS FOR A GIVEN
;IOWD FOLLOWING THE PAGING OF A JOB. PRESERVES T1-T4, P3, P4.
;
;CALL MOVE T2,IOWD
; MOVEI P1,0 ;FIRST CALL
; MOVE P3,LOC OF CHANNEL DATA BLOCK
; MOVE P4,FRAME-COUNT,,CHARS/WD IF TU45
; PUSHJ P,MAPIO
;RETURN CPOPJ IF IOWD EXCEEDS AVAILABLE PAGING REGISTERS
; CPOPJ1 P2=ADDRESS OF FIRST PAGING REGISTER USED
; P1=ADDRESS OF NEXT PAGING REGISTER TO BE USED
MAPIO:: TLNN T2,-1 ;0 OR CHANNEL JUMPS ARE ILLEGAL
STOPCD CPOPJ##,DEBUG,IEZ, ;++IOWD EQUALS ZERO
PUSHJ P,SVEUB ;SAVE AND SETUP UBR
PUSHJ P,SAVT## ;SAVE T REGS
PUSH P,U ;SAVE U
MOVE P1,CHNIMR##(P3) ;UBA #,,1ST ASSIGNED PAGING REGISTER
HRRZI T4,-UBAEXP(P1) ;OFFSET FROM BASE OF UBA PAGING REGISTERS
LSH T4,P2WLSH## ;CONVERT TO PAGES
MOVE U,T2 ;SAVE IOWD IN U
AOS T2 ;ACCOUNT FOR FACT THAT IOWD'S ARE ADDR-1
ANDI T2,PG.BDY## ;GET LOW 9 BITS OF STARTING ADDRESS
ADD T4,T2 ;FORM STARTING "DOUBLE-WORD" -11 ADDRESS
LSH T4,2 ;TURN INTO BYTE ADDRESS
MOVEM T4,CHNIEA##(P3) ;AND SAVE IN CHANNEL DATA BLOCK
MOVE T4,CHNMRC##(P3) ;GET MAPPING REGISTER COUNT
MOVE T2,U ;T2 AND U = IOWD
HLROS U ;U = -WORD COUNT
MOVEI T2,1(T2) ;STARTING ADDRESS
PUSHJ P,V2PADR ;SEE WHAT KIND OF REFERENCE THIS IS
JFCL ;ILLEGAL, WE'LL CATCH IT LATER
TLZE P1,(1B0) ;EXEC?
CAIE T2,1 ;YES, "NO DATA XFER" TYPE IOWD? (INCREMENTED)
JRST MAPIO1 ;NO, CONTINUE
MOVEI T2,CHNDBF##(P3) ;YES, POINT TO ADDRESS OF DUMMY BUFFER
SETOM CHNNXF##(P3) ;SET FLAG FOR DEVICE DRIVER TO SET ADDRESS INH
MAPIO1: MOVE T1,T2 ;ANOTHER ADDRESS (THIS BECOMES A FLAG)
MAPIO2: PUSHJ P,V2PADR ;GET PHYSICAL ADDRESS IN T3
SKIPGE USRHCU## ;IF SAVE IN PROGRESS
SKIPA ;THEN, WE LET ERROR PASS
STOPCD .,JOB,AAO, ;++ACCESS ALLOWED OFF (BUT THE IOWD ADDRESS CHECKED)
TLZ P1,(1B0) ;CLEAR EXEC ADDRESS FLAG
LSH T3,W2PLSH## ;GET PAGE NUMBER FOR UBA MAPPING
PUSHJ P,SETUBB ;GO SET PROPER UBA BITS IN T3
WRIO T3,(P1) ;AND LOAD THE PAGING RAM
JUMPE T1,MAPIO3 ;IF NOT FIRST PAGE, DO WHOLE PAGE
ANDI T1,PG.BDY## ;EXTRACT THE WORD NUMBER
SUBI T1,PAGSIZ## ;CALCULATE THE NUMBER OF WORDS DONE IN FIRST PAGE
CAIA ;SKIP PASS 2 CODE
MAPIO3: MOVNI T1,PAGSIZ## ;(- # DONE)
SUB U,T1 ;-#LEFT = -#LEFT --#DONE
JUMPGE U,MAPIO6 ;JUMP IF THE ORIGIONAL WORD COUNT IS EXHAUSTED
MOVEI T1,0 ;START NEXT PAGE AT ADDRESS 0
ADDI P1,1 ;POINT TO NEXT MAPPING REGISTER
ADDI T2,PAGSIZ## ;STEP TO NEXT PAGE
SOJG T4,MAPIO2 ;CONTINUE IF THERE IS ROOM
; JRST MAPI5A ;WHOOPS! OUT OF PAGING REGISTERS
SETZ P1, ;INDICATE NONE
STOPCD (UPOPJ##,JOB,OMR) ;++OUT OF MAPPING REGISTERS
;HERE WITH ENTIRE IOWD MAPPED
;U/ NUMBER OF WORDS OF LAST PAGE MAPPED BUT NOT USED
MAPIO6: HRRZ P2,P1 ;GET LAST USED REGISTER ADDRESS
MOVNS U ;NEGATE U (NOW - XTRA WDS MAPPED)
ANDI U,PG.BDY## ;WORDS INTO LAST PAGE TO TRANSFER
SKIPN U ;JUST CROSSED PAGE BOUNDARY?
AOS P2 ;YES, ACCOUNT FOR IT
LSH U,2 ;MAKE INTO AN ELEVEN STYLE ADDRESS
HRRZI P2,-UBAEXP(P2) ;GET OFFSET INTO MAPPING REGISTERS
IMULI P2,UBAMUL ;MAKE INTO 11 STYLE ADDRESSING
ADDB P2,U ;FORM ADDRESS OF LAST WORD TO TRANSFER
SUB U,CHNIEA##(P3) ;MINUS STARTING ADDRESS
TLNE P4,-1 ;USER FRAME COUNT?
HLRZ U,P4 ;YES, BELIEVE USER
MOVEM U,CHNBTC##(P3) ; AND SAVE THE TOTAL BYTE COUNT
SKIPGE CHNNXF##(P3) ;IS THIS A NO-XFER REQUEST?
MOVE P2,CHNIEA##(P3) ;YES--THEN ENDING ADDRESS WILL EQUAL STARTING ADDR
SKIPGE P3 ;WANT TERMINATION EXPECTED?
MOVEM P2,CHNTCW##(P3) ;STORE FOR LATER CHECKING
MOVE P2,CHNIMR##(P3) ;GET ADDRESS OF INITIAL MAPPING REGISTER
PJRST UPOPJ1## ;SKIP RETURN
;ROUTINE TO SET THE PROPER BITS FOR A UBA PAGING RAM ENTRY WHICH IS IN T3.
;THE BIT SETTINGS DEPEND ON WHAT KIND OF A DEVICE IS BEING RUN THROUGH MAPIO.
SETUBB: PUSHJ P,SAVE1## ;SAVE P1
SKIPN P1,DEVMOD(F) ;PICK UP DEVICE CLASSES
MOVEI P1,DVDSK ;MUST BE READING HOME BLOCKS
TRO T3,UNBVBT ;ALWAYS SET VALID
SKIPE CHNRRV##(P3) ;ARE WE DOING A READ REVERSE OPERATION?
TRO T3,UNBRRV ;YES--SET READ REVERSE
IFN FTSPL,<
SKIPL DEVSPL(F) ;SPOOLED DDB'S ARE ALWAYS DISKS
>;FTSPL
TLNE P1,DVDSK ; OR IF A "REAL" DISK DDB
TRO T3,UNB36B ; SET FAST XFER MODE
IFN FTSPL,<
SKIPGE DEVSPL(F) ;IF A SPOOLED DDB (I.E. DISK)
POPJ P, ; WE'RE DONE
>;FTSPL
TLNE P1,DVLPT!DVCDR ;IF AN LP20 OR CD20
TRO T3,UNBD18 ; SET 18 BITS DISABLE (16 BIT MODE)
POPJ P, ;RETURN
;ROUTINE TO TURN A VIRTUAL ADDRESS INTO A PHYSICAL ONE.
;WORRIES ABOUT WHAT SORT OF VIRTUAL ADDRESS IT MIGHT BE (EXEC, USER...)
;
;CALL: T2/ADDRESS TO MAP
; F/DDB THAT WANTS IO
; PUSHJ P,V2PADR
; HERE WHEN PAGE ISN'T ACCESSIBLE (USUALLY RESULTS IN AN AAO)
; HERE WHEN MAPS OK, T3 IS PHYSICAL ADDRESS.
;
;ONLY T3 IS TRASHED
V2PADR: MOVE T3,DEVMOD(F) ;GET DEVMOD
IFE FTSPL,<
TLNN T3,DVDSK!DVLPT!DVCDR ;IF A DSK (OR LP20 OR CD20)
>
IFN FTSPL,<
SKIPL DEVSPL(F) ;SPOOLED DDBS ARE ALWAYS A DSK
TLNE T3,DVDSK!DVLPT!DVCDR ;IF A DSK (OR LP20 OR CD20)
CAIA ;MONITOR IO IS POSSIBLE
>
SKIPN T3 ;IF MIGHT BE READING HOME BLOCK
SKIPL S ; SKIP IF MONITOR IO
SKIPA T3,[PXCT 4,[MAP T3,(T2)]] ;NOT MONITOR SPACE, MAP AS USER
TLOA P1,(1B0) ;REMEMBER THIS IS EXEC
TLZA P1,(1B0) ;THIS IS NOT
MOVSI T3,(MAP T3,(T2));MONITOR IO, MAP AS EXEC ADDRESS
IFN FTXMON,< ;SHOULD A KS EVER DO EXTENDED SECTIONS
HRL T2,DEVISN(F) ;SECTION NUMBER FOR IO
PUSHJ P,SSEC1 ;ENTER SECTION 1
>
XCT T3 ;MAP EXEC OR USER, RESULT IN T3
TLNN T3,(1B8) ;PAGED REFERENCE? (OUGHTA BE 1)
JRST V2PAD1 ;NO, WILL NOT FAULT
TLNN T3,(1B1) ;HARD PAGE FAILURE?
TLNN T3,(17B5) ;...
POPJ P, ;YES TO EITHER, ACCESS DENIED
V2PAD1: TLZ T3,777760 ;ACCESS IS OK, CLEAR ACCESS BITS
JRST CPOPJ1## ;RETURN SUCCESS
;ROUTINE TO INVALIDATE ENTIRE CACHE AND VALIDATE CORE
; ALWAYS RETURN CPOPJ, SAVING ALL T ACS.
CSDMP:: WREBR @.CPEBR ;CAUSE CACHE FLUSH
AOS .CPCSN## ;COUNT THE SWEEP
POPJ P, ;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
CPSMPS::PUSHJ P,MAPLOC## ;GET EXEC MAP SLOT
MOVE W,T1 ;SAVE BYTE POINTER TO EXEC MAP SLOT
MOVSI P3,(<PM.DCD>B2+PM.WRT+PM.PUB)
LDB T4,[POINT 14,NWCORE##,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
CLRPT (P1) ;CLEAR HDW PAGE TABLE FOR NEW MAPPING
MOVEI T2,PAGSIZ## ;NO. OF WORDS/PAGE TO SCAN
WREBR @.CPEBR## ;INVALIDATE CACHE
SETOM .CPPSP## ;SET SWEEPING FLAG
CPSMPI::MOVE P2,(P1) ;TEST NEXT LOCATION
MPSLP2: SOJLE T2,MPSLP1 ;IF CURRENT PAGE DONE, MAP NEXT
AOJA P1,CPSMPI ;GO TEST NEXT WORD IN PAGE
;HERE ON BAD WORD FOUND (NXM OR PARITY) - TRAP HAPPENED AND ADDED 3 TO PC
MAP T1,(P1) ;GET THE PHYSICAL ADDRESS OF BAD WORD
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
LDB P1,[POINT 22,T1,35] ;GET JUST THE PHYSICAL ADDRESS OF BAD WORD
PUSHJ P,CPIASN## ;CONVERT TO SEG NUMBER IN J
TDZA T1,T1 ;INDICATE NO ERROR IN MONITOR OR JOB
SETO T1, ;INDICATE AN ERROR IN MONITOR OR 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
SETZM .CPPTH## ;CLEAR FLAG THAT TRAP HAPPENED
JRST MPSLP2 ;GO CONTINUE THE SWEEP
MPSLP5: SETZM .CPPSP## ;CLEAR SWEEPING FLAG
PUSHJ P,UNMAP## ;RESTORE EXEC MAP SLOT
POPJ P, ;AND RETURN
$LIT
KSEND: END