Trailing-Edge
-
PDP-10 Archives
-
BB-AS80B-SM_1985
-
sources/io.mic
There are 5 other files named io.mic in the archive. Click here to see a list.
.TOC "I/O INSTRUCTIONS"
; BITS 10-12 OF INSTRUCTION GET MAPPED TO IR 7-9 FOR I/O INSTRUCTIONS
; THE DEVICE ADDRESS IS BROKEN DOWN AS ONE OF THE FIRST 7, OR ALL OTHERS
.DCODE
;DEVICE 000 (APR)
700: W, J/APRBI ;APRID (BLKI APR,) OPTIONS, SERIAL #
W, DATAI, J/APRDI ;DATAI APR, ADDRESS COMPARE
I, J/APRBO ;WRFIL (BLKO APR,) REFILL RAM
R, DATAO, J/APRDO ;DATAO APR, ADDRESS COMPARE
I, CONO, J/APRCO ;CONO APR, APR FLAGS
I, CONI, J/APRCI ;CONI APR,
I, CONSZ, J/APRCI ;CONSZ APR,
I, CONSO, J/APRCI ;CONSO APR,
;DEVICE 004 (PI)
710: W, M, J/PIBI ;RDERA (BLKI PI,) READ ERA
W, B/3, J/PIDI ;DATAI PI, Stats, or not used
R, J/PIBO ;SBDIAG (BLKO PI,) SBUS DIAGNOSTIC
R, B/0, J/PIDO ;DATAO PI, More statistics
I, CONO, J/PICO ;CONO PI, PI SYSTEM CONTROL
I, CONI, J/PICI ;CONI PI, IN PROGRESS, ENABLE
I, CONSZ, J/PICI
I, CONSO, J/PICI
;DEVICE 010 (PAG)
720: RW, BLKI, J/PAGBI ;BLKI PAG, UNASSIGNED
W, DATAI, J/PAGDI ;DATAI PAG, USER CONTEXT
I, J/PAGBO ;CLRPT (BLKO PAG,) INVAL PAGE TABLE
R, DATAO, J/PAGDO ;DATAO PAG, USER CONTEXT
I, CONO, J/PAGCO ;CONO PAG, EXEC CONTEXT
I, CONI, J/PAGCI ;CONI PAG,
I, CONSZ, J/PAGCI
I, CONSO, J/PAGCI
;DEVICE 014 (CCA)
730: I, J/SWEEP ;BLKI CCA, 8 FUNCTIONS TO SWEEP THE CACHE
I, J/SWEEP ;SWPIA (DATAI CCA,)INVALIDATE CACHE, NO CORE UPDATE
I, J/SWEEP ;SWPVA (BLKO CCA,)VALIDATE CORE, LEAVE CACHE VALID
I, J/SWEEP ;SWPUA (DATAO CCA,)UNLOAD CACHE TO CORE, CLEAR CACHE
I, J/SWEEP ;CONO CCA,
I, J/SWEEP ;SWPIO (CONI CCA,)INVALIDATE ONE PAGE
I, J/SWEEP ;SWPVO (CONSZ CCA,)VALIDATE ONE PAGE
I, J/SWEEP ;SWPUO (CONSO CCA,)UNLOAD ONE PAGE
;I/O CONT'D
;DEVICE 020 (TIM)
740: W, B/1, J/RDMTR ;RDPERF (BLKI TIM,) PERF CNT
W, B/0, J/RDMTR ;RDTIME (DATAI TIM,) TIME BASE
R, DATAO, J/TIMBO ;WRPAE (BLKO TIM,) PA ENABLES
R, DATAO, J/TIMDO ;DATAO TIM, UNDEFINED
I, CONO, J/TIMCO ;CONO TIM, SETUP INTERVAL TIMER
I, CONI, J/TIMCI ;CONI TIM, RD INTERVAL & PERIOD
I, CONSZ, J/TIMCI
I, CONSO, J/TIMCI
;DEVICE 024 (MTR)
750: W, B/3, J/RDMTR ;RDMACT (BLKI MTR,) CACHE CNT
W, B/2, J/RDMTR ;RDEACT (DATAI MTR,) EBOX CNT
I, J/UUO ;BLKO MTR, UNDEFINED
I, J/UUO ;DATAO MTR, UNDEFINED
I, CONO, J/MTRCO ;WRTIME (CONO MTR,) ACCT & TB CTL
I, CONI, J/MTRCI ;CONI MTR, SAME
I, CONSZ, J/MTRCI
I, CONSO, J/MTRCI
;DEVICE 030
760: RW, BLKI, J/BLKIO
W, DATAI, J/IO
RW, BLKO, J/BLKIO
R, DATAO, J/IO
I, CONO, J/CONO
W, CONI, J/IO
I, CONSZ, J/CONS
I, CONSO, J/CONS
;DEVICES 034-774 (ALL OTHERS)
770: RW, BLKI, J/BLKIO
W, DATAI, J/IO
RW, BLKO, J/BLKIO
R, DATAO, J/IO
I, CONO, J/CONO
W, CONI, J/IO
I, CONSZ, J/CONS
I, CONSO, J/CONS
.UCODE
.TOC "EXTERNAL DEVICE I/O INSTRUCTIONS"
=0****00*000
BLKIO: SKP IO LEGAL,CALL,J/IOCHK ;FIRST VERIFY INSTR VALIDITY
BYTE DISP,J/BLK1 ;TEST FPD
CONS: ;HERE FOR CONSO, CONSZ TO LOAD
; BR IN CASE OF UUO
CONO: BR/AR,ARL_ARR,ARR_ARR ;CONDITIONS TO BOTH HALVES
=10
IO: AR_MEM,SKP IO LEGAL,CALL,J/GTEBUS;WAIT FOR MBOX IF BLKI/O
RELEEB: REL ECL EBUS,B WRITE ;XFER DONE, WHAT TO DO?
=
=1*010
IOTEND: FIN STORE,MB WAIT,J/BLK4 ;BLKI/BLKO
TEST AR.BR,TEST FETCH,J/NOP ;CONSZ
MEM_AR,SKP PI CYCLE,J/IOFET ;DATA/CON I/O
TEST AR.BR,TEST FETCH,J/NOP ;CONSO
;BLKI/BLKO SCREWED AROUND WITH TO TRY TO STOP PI LOSSAGE
BLK4: TEST BRL,TEST FETCH,SKP PI CYCLE,J/CLRFPD
=1****0
IOFET: I FETCH,J/NOP ;HERE IF NOT PI CYCLE
DISMISS,J/PIFET ;DISMISS INTRPT AFTER DATA/CON I/O
=1**010
BLK2: MEM_AR,BR/AR,ARL_0.C,B DISP,J/BLK3
BLK1: AR_AR+1,GEN CRY18,STORE,J/BLK2 ;UPDATE POINTER WORD
=111 SKP PI CYCLE,J/BLK2 ;IF FPD & NOT PI, DON'T INCREMENT
=1*101 ;DO DATAI OR DATAO
BLK3: VMA_AR,LOAD AR,SET FPD,J/IO ;GET DATA TO OUTPUT
VMA_AR,SET FPD,J/IO ;INPUT DO BEFORE MEM
;;;NOTE NOTE NOTE SET FPD INHIBITED BY HARDWARE IF PI CYCLE (SCD5)
;SUBROUTINES TO HANDLE EBUS
;CALL WITH "SKP IO LEGAL"
;ENTER AFTER LOADING AR IF OUTPUT FUNCTION
=00
GTEBUS: AR_BR,J/UUO ;HERE IF IO ILLEGAL IN THIS MODE
REQ EBUS,CALL,J/WGRANT ;ASK PI SYSTEM FOR BUS
=11 ;RETURN TO TRANSFER ROUTINE
;SUBROUTINE TO PERFORM EBUS TRANSFER
;SETUP CONTROLLER SELECT AND FUNCTION LINES BEFORE CALL
;IF OUTPUT, ALSO PUT AR ONTO EBUS DATA LINES
EBUSX: GEN AR,TIME/5T, ;WAIT AFTER ASSERTING FUNCTION
SET EBUS DEMAND,J/WXFER ; AFTER 300 NS, ASSERT DEMAND
=0
EBUSW: AR_EBUS,GEN AR,
CLR EBUS DEMAND,J/RELEB ;STROBE DATA AND DROP DEMAND
WXFER: GEN AR,SKP -EBUS XFER,J/EBUSW ;WAIT FOR TRANSFER
RELEB: GEN AR,REL EBUS,TIME/5T, ;DROP DATA, CS, AND FCN
RETURN3 ;AFTER 150 NS, THEN RELEASE BUS
;SUBROUTINE TO WAIT FOR PI SYSTEM TO GRANT EBUS
; IT WILL EITHER SEND EBUS GRANT, OR PI READY
=0
WGRANT: SKP -EBUS GRANT,J/WGRNT1 ;GOT IT?
DROP EBUS REQ,J/TAKINT
=0
WGRNT1: IO INIT,GEN AR,J/WGRNT2 ;GOT IT, SETUP CS, FCN, AND DATA
SKP INTRPT,J/WGRANT ;DIDN'T GET IT, TEST FOR INTERUPT
WGRNT2: GEN AR,TIME/5T, ;JUST WAIT
EBUS CTL/IO INIT,RETURN3
;HERE TO START PI CYCLE TRANSFER. HOLD EBUS CTL SELECTION
EBUSI: TIME/5T,EBUS CTL/DATAI,J/EBUSX
EBUSO: GEN AR,TIME/5T,EBUS CTL/DATAO,J/EBUSX
;SUBROUTINES TO CHECK IO LEGALITY FOR INTERNAL I/O INSTRUCTIONS
.IF/MODEL.B
3002:
.IFNOT/MODEL.B
2002: ;ACCESSIBLE ON EXTEND [0]
.ENDIF/MODEL.B
IOCHK: AR_BR,J/UUO ;NAUGHTY, MUST'NT DO
.IF/MODEL.B
3003:
.IFNOT/MODEL.B
2003:
.ENDIF/MODEL.B
RET1: RETURN1 ;ONE-CYCLE NULL ROUTINE
=0
GETEEB: AR_BR,J/UUO ;IO ILLEGAL IN THIS MODE
GTEEB1: GET ECL EBUS,RETURN1
.TOC "INTERNAL DEVICE FUNCTIONS -- APR, CCA"
=0****00***0
SWEEP: BR/AR,SC_#,#/9.,CALL,
SKP IO LEGAL,J/IOCHK ;ALLOWED?
AR_SHIFT ;MOVE PAGE # TO PLACE
= VMA_AR,SWEEP CACHE ;START A SWEEP
MBREL: MB WAIT,J/IFNOP ;COMPLETE REG FUNC BEFORE FETCH
=0****00**00
APRDO: CALL,SKP IO LEGAL,J/GETEEB ;SET ADDR BREAK
DATAO APR,J/RELEEB
APRBO: BR/AR,CALL,SKP IO LEGAL,J/IOCHK ;SET CACHE REFILL ALGORITHM
WR REFILL RAM,J/MBREL ;INFO ALREADY IN VMA
=
=0****00*000
APRDI: CALL,SKP IO LEGAL,J/GETEEB ;READ ADDR BREAK
DATAI APR(L),J/RELEEB
=010
.IFNOT/DDT.BUG ;[346] Normal code
APRBI: CALL,SKP IO LEGAL,J/IOCHK ;RETURN MICRO VERSION, SERIAL #
AR_SERIAL,TIME/3T, ;READ SERIAL NUMBER
CALL,J/UVERS ;GET MICRO-CODE VERSION IN AR
=111 ARL_ARR.S,AR_BR ;COMB SERIAL WITH VERSION
= AR0-8_#,STORE,OPTIONS, ;SET OPTION FLAGS
J/STMEM
.IF/DDT.BUG ;[346] Gross hack to make EDDT work
APRBI: AR_SERIAL,TIME/3T ;[346] Get hardware serial number
=
=0 AR_AR SWAP,FE_#,OPTIONS, ;Set to test bit 23
SKP IO LEGAL,CALL [IOCHK]; Is this a legal instruction here?
GEN P AND #,#/1,SKP SCAD NZ ;Was bit 23 set?
=0*0
SEROK: AR_AR SWAP,CALL [UVERS] ;Maybe not. Get microcode version
P_P AND #,#/76,J/SERFIX ;Yes. Clean it and move it
ARL_ARR,ARR_BR ;It's fixed. Shuffle version to spot
= AR0-8_FE,STORE,J/STMEM ;Move in options and store result
;
SERFIX: FE_FE+#,#/10,J/SEROK ;OR in bit 5 for option
.ENDIF/DDT.BUG ;[346] All this code is GROSS!!
=0****00**00
APRCO: BR/AR,ARL_ARR.M,ARR_ARR,CALL.M, ;SET APR FLAGS
SKP IO LEGAL,J/GETEEB
CONO APR, J/APRCO7 ;[272]
APRCI: BR/AR,CALL,
SKP IO LEGAL,J/GETEEB ;READ APR FLAGS
CONI APR(R) ;GET RIGHT HALF OF APR CONDITIONS
= ARX_AR SWAP,CONI APR(L) ;NOW LH COND TO AR LEFT
AR_ARX,ARL_ARL,J/RELEEB ;COMBINE HALVES
APRCO7: CONO APR,J/RELEEB ;[272]
.TOC "INTERNAL DEVICE FUNCTIONS -- PI"
=0****00*000
.IFNOT/INSTR.STAT
PIDO:
PIDI: AR_BR,J/UUO ;DATAI/O PI, UNASSIGNED
.IF/INSTR.STAT
;DATAO PI, SETS UP BUFFER POINTERS FOR TRACKS
;DATAI PI, READS CURRENT BUFFER POINTER
PIDI:
PIDO: BR/AR,ARL+ARX_0.M,CALL.M, ;CHECK IO LEGALITY
SKP IO LEGAL,J/IOCHK
SC_#,#/9.,B DISP,SKP BR0,J/PIDX ;NOW, WHAT TO DO?
.ENDIF/INSTR.STAT
PIBI: READ ERA,J/RDEBRG ;GET AND STORE
=0
PIBO: FE_#,#/7,CALL, ;NUMBER OF TIMES TO TRY
SKP IO LEGAL,J/IOCHK ;SBUS DIAGNOSTIC
DODIAG: SBUS DIAG,BR/AR ;SEND THE DIAG FUNCTION FROM AR
=
.DEFAULT/MOS=0
.IFNOT/MOS
AR/CACHE,VMA_VMA+1,STORE,J/STMEM ;STORE THE RESPONSE
.IF/MOS
AR/CACHE,MB WAIT ;[225]GET THE DATA.
GEN AR+1,SKP AD NE ;IF MEMORY RETURNED -1 TRY AGAIN
=0
FE_FE-1,SKP SCAD0,J/SDTEST ;IT IS SEE IF TOO MANY TRIES
SDONE: VMA_VMA+1,STORE,J/STMEM ;STORE THE RESPONSE
=0
SDTEST: AR_BR,J/DIAG1 ;[225]RECOVER THE FUNC AND RETRY.
AR_0S,J/SDONE ;TOO MANY TRIES QUIT RETURNING 0
.ENDIF/MOS
=0****00*000
PICO: BR/AR,ARL_ARR.M,ARR_ARR,
CALL.M,SKP IO LEGAL,J/PICOM1
=11 CONO PI,J/PICOM2 ;SEND THE DATA
=0****00*100
PICI: BR/AR,CALL,SKP IO LEGAL,J/PICOM1
=11 CONI PI(R) ;READ RH TO AR LEFT
= ARX_AR SWAP, ;RH COND TO ARX RH
CONI PI(PAR) ; AND PARITY ENABLES TO RH
BRX/ARX,ARX_AR, ;READY TO COMB RH PARTS
CONI PI(L) ; AND LH TO AR LEFT
AR_ARX*BRX,AD/OR,ARL_ARL ;COMBINE THEM
PICOM2: REL EBUS,GEN AR,B WRITE,J/IOTEND
=0
PICOM1: AR_BR,J/UUO ;LOSE
REQ EBUS,J/WGRANT ;OK, WAIT TO GET FULL EBUS
.TOC "TRACKS SUPPORT"
;
; According to the University of Essex, when TRACKS is used with
; address break enabled, the monitor cannot disable address break
; for the actual execution of the instruction unless we include
; "ABORT INSTR" as part of the TRACKS loop. Accordingly, this is
; now done for all the different flavors of TRACKS. Thanks, folks.
;
;[317] During an attempt to implement uncounting of doubly counted op
; codes for the OP.CNT conditional, we learned: (1) EA
; calculation requires that VMA be initialized to the instruction
; location (usually PC) for the local/global stuff to work properly.
; Beware! (This is important if you try to do something after
; fetching an instruction but before you EA calc it.) (2) NICOND
; clears the trap enable flag. If INSTR.STAT is on, this will force
; the dispatch to the statistics logic without taking the trap,
; which will thus be lost and gone forever. This is a hardware bug,
; but it's rather impossible to ECO it at this late date.
;
;[321] The solution to this is to ignore the statistics flag if a trap
; is ready. See the block at NEXT for details. (It's not really
; a hardware bug after all.)
;
.IF/INSTR.STAT
=00
PIDX: CLR TRACKS EN,J/IFNOP ;TURN TRACKS OFF
.IF/TRACKS
ARX_SHIFT,ARL_BRL,ARR_0.S,J/PIDO2
.IFNOT/TRACKS
ARX_SHIFT,AR_2,J/PIDX1 ;[315] Turn statistics on
.ENDIF/TRACKS
=11 AR_TRX ;READ BACK POINTER
ARL_0.M ;GET INDEX PART
AR_AR+TRB,STORE,J/STMEM ;DONE WITH DATAI
.IFNOT/TRACKS
PIDX1: AR_ARX+AR*4 ;SAVE PAGE NUMBERS IN TRX REGISTERS
TRB_AR ;INITIAL GARBAGE HERE
VMA_ARX,LOAD AR,PHYS REF
AR_MEM
VMA_ARX+1,LOAD AR,PHYS REF
TRX_AR,ARX_ARX+1 ;[315] Must wait one cycle for
AR_MEM ;parity check before writing AC
VMA_ARX+1,LOAD AR,PHYS REF
TRX1_AR,ARX_ARX+1 ;[315] Note that this will always
AR_MEM ;make it before AR is smashed
VMA_ARX+1,LOAD AR,PHYS REF
TRX2_AR
AR_MEM
SET TRACKS EN ;[315] Might as well do this now
TRX3_AR,I FETCH,J/NOP ;SAVE TABLE PAGE #, TURN ON
.ENDIF/TRACKS
PIDO2: TRX_AR,AR_ARX ;SET UP INDEX
TRB_AR ;AND BASE
SET TRACKS EN,J/IFNOP ;TURN TRACKS ON
.IF/TRACKS
;HERE WHEN NICOND FINDS TRACKS ENABLED
=0
TRK1: TRX_AR,J/TRK2 ;PUT BACK UPDATED INDEX
AR_AR SWAP ;END OF BUFFER. RESET
AR_-AR,J/TRK1 ; ORIGINAL INDEX
TRK2: ARL_0.M
AR_AR+TRB ;ADDRESS TRACKS BUFFER
VMA_AR,PHYS REF ;TO MAKE MODEL A WORK
AR_PC,STORE,PHYS REF ; PUT PC THERE
MEM_AR,VMA/PC,CLR TRACKS EN ;PREVENT NICOND SEEING TRACKS...
ABORT INSTR ;[306] Make address break work by
; copying AD BRK CYC to AD FAIL INH
SET TRACKS EN ;...UNTIL NEXT TIME
DISP/NICOND,J/NEXT ;GO DO NEXT INSTR
.ENDIF/TRACKS
.IF/OP.CNT
;HERE WHEN NICOND FINDS OPCODE COUNTING ENABLED
; SKIP IF USER MODE
;[316] Make this register usage compatible with timing version below by
; making it use TRX2 (for exec mode counts pointer) and TRX3 (for user mode
; counts pointer) instead of TRX and TRX+1.
;[317] A massive attempt to uncount doubly counted instructions when an
; interrupt was detected has been backed off. See INSTR.STAT dispatch logic
; above for commentary.
;
=0
OPCT1: AR_TRX2,SKP AC REF,J/OPCT2 ;[316] TRX HAS PAGE # FOR EXEC TABLE
AR_TRX3,SKP AC REF ;[316] NEXT PAGE IS FOR USER
=0
OPCT2: AR_SHIFT,MQ_SHIFT, ;[317] Save VMA of increment
CLR TRACKS EN,J/OPCT3 ;OPCODE INDEXES INTO TABLE
ARX_FM(VMA),J/OPCT2 ;GET INSTR FROM FM
;
OPCT3: VMA_AR,LOAD AR,PHYS REF ;GET TABLE ENTRY
AR_MEM ;[306] Make address break work
BR/AR,AR_AR+1,STORE ;ADD THIS OCCURANCE TO IT, keep old
MEM_AR,VMA/PC
SET TRACKS EN ;LET US GET BACK NEXT NICOND
DISP/NICOND ;DO INSTR IN ARX
;
; In an attempt to prevent an interrupt after counting an instruction,
; we now fake the second NICOND in line.
;
=0000 AR_BR,CLR TRACKS EN,J/OPFIX ;Some kind of odd condition.
=0010 AR_BR,CLR TRACKS EN,J/OPFIX ; Uncount the instruction
AR_BR,CLR TRACKS EN,J/OPFIX
AR_BR,CLR TRACKS EN,J/OPFIX
AR_BR,CLR TRACKS EN,J/OPFIX
AR_BR,CLR TRACKS EN,J/OPFIX
=1010 BRX/ARX,AR_ARX,SET ACCOUNT EN, ;The usual case
XR,EA MOD DISP,J/COMPEA
AR_BR,CLR TRACKS EN,J/OPFIX
=1110 GEN ARX,LOAD IR,#/0,J/XCTGO ;Instruction in registers
AR_BR,CLR TRACKS EN
;
OPFIX: VMA_MQ,STORE,PHYS REF ;Restore old count
MEM_AR,VMA/PC
SET TRACKS EN ;Turn TRACKS back on
DISP/NICOND,J/NEXT ; and do it yet again
.ENDIF/OP.CNT
.IF/OP.TIME
;HERE TO ADD UP TIME SPENT IN INSTR'S
OPTM0: SC_#,#/9.,SKP USER,J/OPTM1
=0
OPTM1: BR_AR LONG,AR_TRX2,SKP AC REF, ;INSTR IN ARX PAGE IN AR
J/OPTM2
BR_AR LONG,AR_TRX3,SKP AC REF, ;INSTR IN ARX PAGE IN AR
J/OPTM2
=0
OPTM2: AR_SHIFT,ABORT INSTR,J/OPTM3 ;[306] GENERATE ADDR TO INCREMENT
;NEXT GET ADDR FOR THIS
ARX_FM(VMA),J/OPTM2 ;GET NEXT INSTR FROM FM
OPTM3: VMA_AR,LOAD AR,UNCSH PHYS REF ;BUMP COUNT LOCATION
AR_MEM
AR_AR+1,STORE
MEM_AR,SKP USER
=0 AR_TRX,J/OPTM4
AR_TRX1
OPTM4: AR_SHIFT,ARX_TRB
TRB_AR ;SAVE NEXT LOC TO BUMP
RD+CLR PA ;TIME TO AR
MTR CTL/CLR PERF
VMA_ARX,LOAD ARX,UNCSH PHYS REF ;GET TABLE ENTRY
AR_AR-BR,ARL_0.S ;COMPENSATE TIME FOR THIS CODE
BR/AR,ARX_MEM,SKP AR18 ;IF THIS WAS AN ENABLED STATE,
=0 AR_ARX+BR,STORE ;WRITE IT BACK
MEM_AR,VMA/PC ;NOW SETUP NEXT INSTR AGAIN
ARX_BRX,SET TRK+PA EN ;RESTORE STATISTICS FLAGS
DISP/NICOND,J/NEXT
.ENDIF/OP.TIME
;THIS IS THE SECOND ORDER STATISTICS GATHERING CODE
.IFNOT/SO2.CNT
.IF/SO.CNT
;THIS IS NON DEBUGED CODE THAT IS IN A VERY PRIMATIVE STATE
;IT WAS ABANDONED BETWEEN EDITS AS THE MONITOR NEEDED SOMETHING
;SLIGHTLY DIFFERENT
;THIS IS CODE TO DO A SECOND ORDER STATISTIC IN THE SECOND 128K
;EACH ENTRY IS A HALF WORD
;THE LOW ORDER BIT OF <LAST OPCODE><THIS OPCODE> CONCATENATION
;DETERMINES WHICH HALFWORD IS INCREMENTED. OFF IS HIGH
;IF A HALFWORD OVERFLOWS THE CODE TURNS ITSELF OFF AND WRITES -1
;AT LOCATION 400000
;TRX HIDES THE LOCATION PRESENTED TRB THE LAST OPCODE
; THIS IS IN THE NEXT LOOP COMMENTED HERE FOR DOCUMENTATION
;TRK0: ARX_TRB,BRX/ARX,SKP AC REF,J/TRK1;GET PREV INSTR HIDE THIS ONE
=0
TRK1: AR_1,SC_#,#/9.,J/TRK2 ;SHIFT IN FIRST OPCODE
ARX_FM(VMA),AR_ARX ;GET THE INSTRUCTION FROM FM
BRX/ARX,AR_1,SC_#,#/9.,ARX_AR ; WHEN IT HIDES THERE
TRK2: AR_SHIFT,SC_#,#/8.,ARX_BRX ;SETUP TO DO THE NEXT OPCODE
AR_SHIFT,CLR TRACKS EN ;CONVIENT TO SHUT OFF TRACKS
VMA_AR,LOAD ARX,PHYS REF,AR_ARX ;LOW BIT OF INSTR WHERE CAN TEST
ARX_SHIFT,TRB_AR ;LOW BIT OF INSTR TO HIGH BIT
ARL_0.S,ARR_1S,SKP ARX0 ;SEE WHICH HALFWORD TO INC
; ALSO SETTING UP FOR TEST IN
; LOW INCREMENT
=0 ARL_1.M,ARR_0.M,J/TRK3 ;INC HIGH
ARX_MEM ;INC LOW
BR/AR,ARX_ARX+1,AR/ADX,STORE ;INCREMENT LOW HALF AND STORE IT
TEST AR.BR,SKP CRY0 ;USING AND-1 HACK TO TEST OVFLOW
=0 AR_0S,J/TRKLOS ;OVERFLOWED FIXUP TO LOSE
MEM_AR,ARX_BRX,VMA/PC,AR_BRX ;NO OVERFLOW GET OUT ALSO
TRKN1: SET TRACKS EN ; SAVE AWAY THIS OPCODE
TRKND: DISP/NICOND,J/NEXT ;AND DO NEXT INSTR
TRK3: ARX_MEM,BR/AR ;GET WORD TO INC
AR_ARX+BR,STORE,SKP CRY0 ;COMPUTE AND CHECK FOR OVERFLOW
=0 ARX_BRX,VMA/PC,MEM_AR,AR_BRX, ;SAVE AWAY THIS INSTR
J/TRKN1 ; AND GET OUT
AR_0.C,ARX_BRX,MEM_AR,J/TRKLOS ;SHUT DOWN TRACKS ON OVERFLOW
TRKLOS: AR_1,SC_#,#/17. ;WHEN LOSS PUT -1 IN 400000
AR_SHIFT
GEN AR,VMA/AD,PHYS REF ;SHUT OFF TRACKS AND QUIT
AR_TRB,STORE
MEM_AR,VMA/AD
J/TRKND
.ENDIF/SO.CNT
.IF/SO2.CNT
;THIS ONE DOES THE COUNTING IN 128K STARTING AT AN ADDRESS PRESENTED IT
;THIS IS CODE TO DO A SECOND ORDER STATISTIC IN THE SECOND 128K
;EACH ENTRY IS A HALF WORD
;THE LOW ORDER BIT OF <LAST OPCODE><THIS OPCODE> CONCATENATION
;DETERMINES WHICH HALFWORD IS INCREMENTED. OFF IS HIGH
;IF A HALFWORD OVERFLOWS THE CODE TURNS ITSELF OFF AND WRITES -1
;AT LOCATION PRESENTED
;TRX HIDES THE LOCATION PRESENTED TRB THE LAST OPCODE
; THIS IS IN THE NEXT LOOP COMMENTED HERE FOR DOCUMENTATION
;TRK0: ARX_TRB,BRX/ARX,SKP AC REF,J/TRK1;GET PREV INSTR HIDE THIS ONE
=0
TRK1: AR_0S,SC_#,#/9.,J/TRK2 ;SHIFT IN FIRST OPCODE
ARX_FM(VMA),AR_ARX ;GET THE INSTRUCTION FROM FM
BRX/ARX,AR_0S,SC_#,#/9.,ARX_AR ; WHEN IT HIDES THERE
TRK2: AR_SHIFT,SC_#,#/8.,ARX_BRX ;SETUP TO DO THE NEXT OPCODE
AR_SHIFT,CLR TRACKS EN ;CONVIENT TO SHUT OFF TRACKS
AR_AR+TRX ;BUMPS BY NUMBER FED IT
VMA_AR,LOAD ARX,PHYS REF,AR_ARX ;LOW BIT OF INSTR WHERE CAN TEST
ARX_SHIFT,TRB_AR ;LOW BIT OF INSTR TO HIGH BIT
ARL_0.S,ARR_1S,SKP ARX0 ;SEE WHICH HALFWORD TO INC
; ALSO SETTING UP FOR TEST IN
; LOW INCREMENT
=0 ARL_1.M,ARR_0.M,J/TRK3 ;INC HIGH
ARX_MEM,ABORT INSTR ;[306] INC LOW
BR/AR,ARX_ARX+1,AR/ADX,STORE ;INCREMENT LOW HALF AND STORE IT
TEST AR.BR,SKP CRY0 ;USING AND-1 HACK TO TEST OVFLOW
=0 AR_0S,J/TRKLOS ;OVERFLOWED FIXUP TO LOSE
MEM_AR,ARX_BRX,VMA/PC,AR_BRX ;NO OVERFLOW GET OUT ALSO
TRKN1: SET TRACKS EN ; SAVE AWAY THIS OPCODE
TRKND: DISP/NICOND,J/NEXT ;AND DO NEXT INSTR
TRK3: ARX_MEM,BR/AR,ABORT INSTR ;[306] GET WORD TO INC
AR_ARX+BR,STORE,SKP CRY0 ;COMPUTE AND CHECK FOR OVERFLOW
=0 ARX_BRX,VMA/PC,MEM_AR,AR_BRX, ;SAVE AWAY THIS INSTR
J/TRKN1 ; AND GET OUT
AR_0.C,ARX_BRX,MEM_AR,J/TRKLOS ;SHUT DOWN TRACKS ON OVERFLOW
TRKLOS: AR_TRX
GEN AR,VMA/AD,PHYS REF ;WRITE -1 IN PRESENTED LOCATION
AR_TRB,STORE
MEM_AR,VMA/PC ;NEED AN INSTRUCTION TO GIVE
J/TRKND ;TIME TO NICOND AFTER VMA/PC
.ENDIF/SO2.CNT
.ENDIF/INSTR.STAT
.TOC "INTERNAL DEVICE FUNCTIONS -- PAG"
=0****00**00
.IFNOT/KLPAGE
PAGBO: BR/AR,CLR FE,CALL, ;INVALIDATE ONE PAGE TABLE LINE
SKP IO LEGAL,J/IOCHK
PAGBO1: PT SEL_INVAL,J/PTLOOP ;SETUP INITIAL PT WR SELECT
.IF/KLPAGE
PAGBO: AR_0S,BR/AR,CALL, ;CLEAR ONE PAGE TABLE ENTRY
SKP IO LEGAL,J/IOCHK
WR PT ENTRY,J/IFNOP
.ENDIF/KLPAGE
PAGDO: ARX_AR (AD),ARR_ARL,ARL_ARL.M, ;SETUP USER CONTEXT
CALL.M,SKP IO LEGAL,J/GETEEB
DATAO PAG(L),AR_ARX ;SETUP AC BLOCKS, PREV CTXT
= SKP AR2,SC_#,#/9.
=0
TIMCO1: MTR CTL/CONO TIM,J/RELEEB ;DO NOT CHANGE UBR
.IF/PAGCNT ;[327] Count DATAO PAG with bit 2
MQ_AR,AR_TRX3+1 ;[327] Do the count
TRX3_AR,AR_MQ
.ENDIF/PAGCNT ;[327]
FE_P AND #,#/4,MQ_SHIFT, ;[333] Save bit 3 for keep test
SKP AR18,AR_0S ;STORE ACCT?
=0*0 AR0-8_#,#/100,CALL,J/PAGD2 ;YES, START WITH EBOX CNT
VMA_MQ,LOAD UBR,CALL [CLRPT] ;[333] No. Set for page table clear
.IF/BIG.PT ;[333]
=1*1 SKP SC NE,J/KEEPME ;[333] Might keep keep me bits
.IFNOT/BIG.PT
=1*1 PT SEL_INVAL,J/PTLOOP ;SETUP INITIAL PT WR SELECT
.ENDIF/BIG.PT ;[333]
;
; PAGD2 is set up as a subroutine for addressing convenience only.
;
=0
PAGD2: ARX_AR,SC_#,#/13.,CALL,J/EMTR ;UPDATE THE EBOX ACCT
MB WAIT,AR0-8_#,#/140 ;READY TO GET CACHE ACCT
ARX_AR,SC_#,#/13.,J/CMTR ;RETURN ABOVE TO CLR PT
=0****00**00
PAGDI: SC_#,#/70,SKP IO LEGAL,
CALL,J/GETEEB
.IFNOT/MODEL.B
DATAI PAG(L),CALL,J/PCTXT ;FIRST GET AC BLOCKS & CWSX
.IF/MODEL.B
DATAI PAG(L),ARX_1B17-1, ;PUT AC BLKS IN AR,
CALL,J/PCTXT ; [0,,-1] IN ARX
.ENDIF/MODEL.B
PAGBI: AR_BR,J/UUO ;BLKI PAG, IS UNASSIGNED
AR_SHIFT,ARL_BRL,J/RELEEB ;COMBINE UBR WITH AC BLKS, CWSX
=
.IFNOT/MODEL.B
PCTXT: P_SC ;PLUG IN LOAD-ENABLE BITS
=0* BR/AR,AR_0S,READ UBR, ;ASK MBOX FOR UBR LOC'N
CALL,J/XFERW ;NOW READ IT
AR_EBUS REG
.IF/MODEL.B
PCTXT: P_SC,ARX_ARX*8 ;STUFF IN LOAD EN, ARX=7,,-10
BR/AR,AR12-17_PREV SEC,ARX_ARX*8
BR/AR,AR_ARX*BR,AD/ANDCA ;PCS TO BR, LD EN, AC BLKS TO AR
=0* AR_AR*BR,AD/OR,READ UBR, ;LH READY IN AR. GET UBR
CALL,J/XFERW
BR/AR,AR_EBUS REG ;LH TO BR. READ UBR ADDRESS
.ENDIF/MODEL.B
ARX_AR,AR_0S,SC_#,#/27., ;READY TO MOVE INTO POSITION
RETURN3
;CONI/O PAG,
=0****00**00
PAGCO: BR/AR,ARL_ARR.M,ARR_ARR,ARX_0S, ;SET EXEC CONTEXT
SKP IO LEGAL,CALL.M,J/GETEEB
CONO PAG,J/SETEBR ;SET CACHE, SEC, TRAP EN FLAGS
PAGCI: BR/AR,AR_0S,CALL,SKP IO LEGAL, ;READ EXEC CONTEXT
SC_#,#/9.,J/GETEEB
CONI PAG ;READ CACHE, SEC, TRAP EN
=
=0* ARX_AR SWAP,AR_0S,READ EBR, ;SETUP EPT LOC'N TO READ
CALL,J/XFERW
AR_EBUS REG, ;GET EBR IN AR
BRX/ARX,ARX_0S ;SAVE FLAGS IN LH OF BRX
ARX_SHIFT,REL ECL EBUS ;MOVE EBR LOC LEFT
ARR_0.M,ADB/BR,ADA EN/EN,AD/OR,ARL/ADX ;COMBINE, THEN PUT IN RH
AR_AR SWAP,B WRITE,J/IOTEND ;STORE THE RESULT
;HERE TO FINISH CONO PAG,
=000 ;[342]
SETEBR: SC_#,#/9.,CALL,J/SHIFT ;MOVE EBR LOC'N TO POSITION
=010 VMA_AR,LOAD EBR,CALL [CLRPT] ;[333]SETUP EBR
=110 ;[342]SETUP INITIAL PT WR SELECT
KEEPME: PT SEL_INVAL,J/PTLOOP ;[342] FOR NON KLPAGE THIS CAN SEND
; THE USER TO PAGBO1 AND SAVE 1
; UCODE LOCATION
.IF/BIG.PT ;[333] Entry from DATAO
PT SEL_INVAL (KEEP),J/KEEPCL ;[342] Hang on to KEEP pages
.ENDIF/BIG.PT ;[333]
=
=110
PTLOOP: AR_AR+BR,VMA/AD,FE_FE-1, ;SELECT A LINE OF PT
CLR PT LINE,TIME/3T, ;DO THE WORK
BYTE DISP,J/PTLOOP ;LOOP TO CLEAR ALL
PT SEL_NORMAL,J/IFNOP ;RESET PT WR SELECTION
.IF/BIG.PT ;[333]
=110
KEEPCL: AR_AR+BR,VMA/AD,FE_FE-1,TIME/3T,;SELECT A LINE OF PT
CLR PT LINE (KEEP), ;DO THE WORK
BYTE DISP,J/KEEPCL ;Hang onto lines with KEEP ME set
PT SEL_NORMAL,J/IFNOP ;RESET PT WR SELECTION
.ENDIF/BIG.PT ;[333]
;
; [333] Set up to clear hardware page table after setting EBR or
; UBR. KEEP ME pages may or may not be cleared, depending upon the
; setting of DATAO PAG bit 3. (Clear everything for CONO PAG.)
;
CLRPT: AR_0S,ARX_0S,REL ECL EBUS ;[334]DON'T HANG UP BUS FOR THIS
=0 AR0-8_#,#/10,MB WAIT, ;WAIT FOR U/E BR LOAD
SC_FE,CALL [ARSWAP] ;[334]GET 1B23
BR/AR,AR_0S,VMA/AD, ;[333][334] START CLEARING AT ZERO
FE_#,#/63.,RETURN4 ;SETUP LOOP COUNT
.TOC "INTERNAL DEVICE FUNCTIONS -- TIM & MTR"
=0****00***0
RDMTR: AR_BR,CALL, ;GET E TO AR
SKP IO LEGAL,J/GETEEB ;GRAB CONTROL OF EBUS
MQ_AR,AR_0S, ;SAVE E IN MQ
SC_#,#/13.,B DISP ;WHICH COUNTER?
=
=00 AR_TIME BASE,J/RDMTR1 ;DATAI TIM,
AR_PERF CNT,J/RDMTR1 ;BLKI TIM,
AR_EBOX CNT,J/RDMTR1 ;DATAI MTR,
AR_CACHE CNT,J/RDMTR1 ;BLKI MTR,
=0
RDMTR1: ARL+ARX_0.M,B DISP, ;SHIFT COUNT INTO POSITION
CALL.M,J/MTRDBL ;ADD DOUBLE WORD FROM PT
AR_AR+BR LONG,REL ECL EBUS
VMA_MQ,STORE,SC_#,#/35.,J/DMVM1 ;STORE TOTAL AT E & E+1
=0****00**00
TIMCO: BR/AR,CALL,SKP IO LEGAL,J/GETEEB
CONO TIM,J/TIMCO1
TIMCI: BR/AR,AR_0S,CALL,
SKP IO LEGAL,J/GETEEB
AR_INTERVAL ;INTERVAL GOES TO LH
= ARX_AR SWAP,AR_0S
AR_PERIOD ;PERIOD TO RH
TIMBO1: MTR CTL/LD PA LH, ;KEEP MTR DECODE FOR TIMBO
ARL_ARXL,J/RELEEB ;COMBINE PERIOD WITH INTERVAL
=0****00**00
MTRCO: BR/AR,ARL_ARR.M,ARR_ARR,
CALL.M,SKP IO LEGAL,J/GETEEB
CONO MTR,J/MTRCO1
MTRCI: BR/AR,AR_0S,CALL,
SKP IO LEGAL,J/GETEEB
CONI MTR ;READ BACK CONDITIONS
=
MTRCO1: ARL_0.S,MTR CTL/CONO MTR,J/RELEEB
=0****00**00
TIMDO: AR_BR,J/UUO ;DATAO TIM, UNDEFINED
=10
TIMBO: ARX_AR,AR_0S,CALL, ;SAVE ENABLES, CLEAR AR
SKP IO LEGAL,J/GETEEB ;CHECK LEGALITY, GET BUS
BLKO TIM(L),AR_ARX ;TURN OFF BY CLEARING LH ENABLES
= BLKO TIM(R),AR_AR SWAP ;SEND RH
BLKO TIM(L),J/TIMBO1 ;SEND LH, TURNING ON AGAIN
;HERE WHEN METER INCREMENT REQUEST DETECTED
MTRREQ: GET ECL EBUS ;TAKE CONTROL OF BUS
AR_MTR REQ ;WHAT TYPE REQUEST?
=0 MQ_AR,AR_AR*2,CALL, ;GET READY TO DISP
VMA_#,#/514,J/MTRRQ0
REL ECL EBUS ;DONE
MB WAIT,SET ACCOUNT EN,J/PIFET ;FETCH NEXT INSTR
MTRRQ0: ARX_AR SWAP,DISP/SH0-3,AR_0S, ;DISPATCH ON REQUEST TYPE
SC_#,#/13.
=000
RD+CLR TB,J/TMTR1 ;TIME BASE
RD+CLR PA,J/PMTR1 ;PERF ANALYSIS CNT
EMTR: RD+CLR E CNT,J/EMTR1 ;EBOX CNT
CMTR: RD+CLR C CNT,J/CMTR1 ;CACHE CNT
REL ECL EBUS ;INTERVAL -- VECTOR INTERRUPT
= SET PI CYCLE
SET ACCOUNT EN,J/PIINST
TMTR1: MTR CTL/CLR TIME,J/MTRRQ1 ;HOLD SELECTS FOR
PMTR1: MTR CTL/CLR PERF,J/MTRRQ1 ;MTR CTL FUNCTION
EMTR1: MTR CTL/CLR E CNT,J/MTRRQ1 ; TO PREVENT RACE
CMTR1: MTR CTL/CLR M CNT,J/MTRRQ1 ; AND POSSIBLE GLITCHES
;HERE WITH RELEVANT COUNT IN ARR, GARBAGE IN ARL
MTRRQ1: ABORT INSTR
=0 ARL+ARX_0.M,ARX0-3 DISP, ;CLEAR GARBAGE & RE-DISPATCH
CALL.M,J/MTRDBL ; TO ADD DOUBLE COUNTER FROM PT
AR_AR+BR LONG,SC_#,#/35.,
VMA_VMA-1,STORE ;STORE BACK IN PROCESS TABLE
MEM_AR,AR_0S ;HI PART TO MEM
AR_SHIFT,VMA_VMA+1,STORE,RETURN1
;HERE TO PICK UP DOUBLEWORD FROM PROCESS TABLE
; AND ADD CURRENT CONTENTS OF APPROPRIATE METER
=00
MTRDBL: AR_0S,ARX_SHIFT,
VMA_#,#/510,J/RDEMTR ;TIME BASE IN EPT 510-511
AR_0S,ARX_SHIFT,
VMA_#,#/512,J/RDEMTR ;PERF CNT IN EPT 512-513
AR_0S,ARX_SHIFT,
VMA_#,#/504,J/RDUMTR ;EBOX ACCT IN UPT 504-505
AR_0S,ARX_SHIFT,
VMA_#,#/506,J/RDUMTR ;CACHE ACCT IN UPT 506-507
RDEMTR: BR_AR LONG, ;SAVE COUNT IN BR!BRX
LOAD AR,EPT REF,J/RDMTR2;GET HIGH WORD FROM EPT
RDUMTR: BR_AR LONG,LOAD AR,UPT REF ; OR UPT AS APPROP
=0*
RDMTR2: FIN XFER,VMA_VMA+1,LOAD ARX, ;NOW GET LOW WORD
CALL,J/XFERW ;GO WAIT FOR IT
ARX_ARX*2,RETURN1
.TOC "PRIORITY INTERRUPT PROCESSING"
;HERE WHEN PRIORITY INTERRUPT REQUEST DETECTED
;PI LOGIC HAS DONE HANDSHAKE TO BRING FUNCTION WORD IN ON EBUS
; FUNCTION WORD IS NOW IN AR, SC=2
;THE FORMAT OF THE FUNCTION WORD IS --
; 0-2 ADDRESS SPACE FOR THE FUNCTION
; 0=EPT
; 1=EXEC VIRTUAL
; 4=PHYSICAL
; OTHERS UNDEFINED
; 3-5 FUNCTION TO PERFORM (SEE LIST BELOW AT PIDISP)
; 6 FUNCTION QUALIFIER
; 7-10 PHYSICAL DEVICE # ON EBUS
; 11-12 UNDEFINED
; 13-35 ADDRESS FOR FUNCTION
PICYC1: SET PI CYCLE,MQ_AR ;START PI CYCLE
FM[SV.IOP]_AR ;[234] save IOP function word
; in AC3.
VMA_AR AND ADMSK,ARX/AD,SH DISP ;EXTRACT ADDR, DISP ON FCN
=1000 ;3-5 IS FUNCTION TO PERFORM
PIDISP: VMA_40+PI*2,J/PIINST ;(0) STANDARD INTERRUPT
VMA_40+PI*2,J/PIINST ;(1) DITTO
AR_AR*4,SC_#,#/5,J/PIVECT ;(2) VECTOR
LOAD AR,J/PIINCR ;(3) INCREMENT
SKP AR6,J/PIDATO ;(4) DATAO
BRX/ARX,TIME/5T,J/PIDATI ;(5) DATAI
AR_AR*4,SKP AR6,J/PIBYTE ;(6) BYTE TRANSFER
.IFNOT/IPA20 ;[265]
VMA_40+PI*2,J/PIINST ;(7) UNDEFINED
.IF/IPA20 ;[265]
VMA_AR AND ADMSK, J/PHYS0 ;(7) KLIPA [265]
.ENDIF/IPA20
PICYC2: VMA_41+PI*2,J/PIINST ;2ND PART OF STD INT
PIVECT: FE_# AND S,#/30,AR_0S,SH DISP ;WHAT KIND OF DEVICE?
=0011
PIINST: EPT FETCH,J/XCTW ;CHAN 0-3
EPT FETCH,J/XCTW ;CHAN 4-7
AR0-8_FE+#,#/142,J/DTEVEC ;DTE 0-3
LOAD ARX,J/XCTW ;EXTERNAL DEVICE
=0*
DTEVEC: ARX_AR,AR_0S,SC_#,#/9.,CALL,J/SHIFT
VMA_AR,EPT FETCH,J/XCTW
=0101
PILD: LOAD AR,EPT REF,J/XFERW ;GET DATUM FROM EPT
LOAD AR,J/XFERW ; OR EXEC VIRTUAL ADDR SPACE
.IFNOT/MODEL.B
VMA_ARX,LOAD AR,
PHYS REF,J/XFERW ; OR PHYSICAL MEMORY, AS REQUESTED
.IF/MODEL.B
VMA_ARX AND ADMSK,ARX/AD,J/PHYS2;FORCE AC'S FOR 0-17
.ENDIF/MODEL.B
.IFNOT/MODEL.B ;[224]
IOPFIN: SET ACCOUNT EN,J/PIDONE ;IN CASE OF EBUS PROBLEMS
.ENDIF/MODEL.B ;[224]
;HERE TO PERFORM INCREMENT FUNCTION
PIINCR: AR_MEM,SKP AR6 ;GET WORD, INCR OR DECR?
=0 AR_AR+1,STORE,J/PIDONE
AR_AR-1,STORE,J/PIDONE
;HERE FOR DATAO (EXAMINE) FUNCTION
=0000
PIDATO: AR0-3 DISP,CALL.M,J/PILD ;GET DATA FROM REQUESTED ADR SPC
AR_AR*4,CALL,J/RDEX ;RESTRICTED EXAMINE
PIOUT: AR_MEM,SET DATAO,CALL,J/EBUSO ;SEND DATA
PIDONE: MEM_AR,DISMISS ;DONE, DISMISS & RESUME NORMAL
PIFET: VMA/PC,FETCH,J/NOP ;RESUME AS BEFORE
=0101 VMA_AR-1,CALL,J/DEXCHK ;GO PROT/RELOC THIS EXAM
.IFNOT/MODEL.B
=0111 VMA_ARX,LOAD AR,PHYS REF,J/PIOUT;PROTECTED PHYSICAL
.IF/MODEL.B
=0111 VMA_ARX AND ADMSK,ARX/AD,J/PHYS1;FORCE AC'S FOR 0-17
.ENDIF/MODEL.B
=1111 J/PIOUT ;PROT VIOLATION. SEND 0
;HERE FOR DATAI (DEPOSIT) FUNCTION
=10
PIDATI: SET DATAI,TIME/5T,CALL,J/EBUSI ;READ THE DATA
ARX_AR,AR_MQ ;DATUM TO ARX, GET FCN WORD
BRX/ARX,ARX_BRX,SKP AR6 ;RESTRICTED?
=0000 AR0-3 DISP,AR_BRX,J/PIST ;NO, STORE AS REQUESTED
AR_AR*4,CALL,J/RDEX ;YES, GET PROT/RELOC ADDR
=0101 VMA_AR+1,CALL,J/DEXCHK ;VERIFY LEGALITY
=0111 AR_BRX,J/PSTOR ;DATA IN AR, ADDR IN ARX. STORE PHYS
=1111 J/PIDONE ;PROT VIOLATION, STORE NOTHING
=0101
PIST: STORE,EPT REF,J/PIDONE
STORE,J/PIDONE
.IFNOT/MODEL.B
PSTOR: VMA_ARX,STORE,PHYS REF,J/PIDONE
.IF/MODEL.B
PSTOR: VMA_ARX AND ADMSK,ARX/AD,J/PHYS3;FORCE AC'S FOR 0-17
.ENDIF/MODEL.B
J/PIDONE
RDEX: FE_# AND S,#/30,AR_ARX ;DTE# *8 TO FE, ADDR TO AR
BR/AR,AR0-8_FE+#,#/145 ;SAVE ADDR TO BR, GET EPT LOC
GTAR08: ARX_AR,AR_0S,SC_#,#/9.
AR_SHIFT,RETURN4
=0*
DEXCHK: CALL,J/PILD ;PROTECTION WORD FROM EPT
SKP AR GT BR ;ALLOWED?
=00 AR_0S,RETURN12 ;NO, SEND 0, STORE NOTHING
VMA_VMA+1,CALL,J/PILD ;YES, GET RELOCATION WORD
=11 AR_AR+BR ;RELOCATE TO PHYSICAL ADDR
ARX_AR AND ADMSK,RETURN2 ;STRIP TO 23 BITS
.IF/IPA20
;BEGIN EDIT [265]
PHYS0: LOAD AR, PHYS REF CACHE ;[311]START READ
AR_MEM ;FINISH READ
=10 AR_AR+1, SET DATAO, ;INCREMENT THE LOCATION
CALL [EBUSO] ;AND SEND DATA OVER THE EBUS
STORE, PHYS REF CACHE, ;[311]UPDATE MEMORY
J/PIDONE ;FINISH MEMORY CYCLE
.ENDIF/IPA20 ;END EDIT [265]
;FORCE AC'S FOR 0-17
.IF/MODEL.B
=00
PHYS1: SC_#,#/32.,CALL,J/CHKAC ;DATAO (EXAMINE)
=10 LOAD AR,J/PIOUT ;AC REF DONT USE PHYS REF
LOAD AR,PHYS REF,J/PIOUT ;NOT AC'S GET PHYSICAL MEMORY
=00
PHYS2: SC_#,#/32.,CALL,J/CHKAC ;DATAO (EXAMINE)
=10 LOAD AR,J/XFERW
LOAD AR,PHYS REF,J/XFERW ;NOT AC'S GET PHYSICAL MEMORY
=00
PHYS3: SC_#,#/32.,CALL,J/CHKAC
=10 STORE,J/PIDONE
STORE,PHYS REF,J/PIDONE
CHKAC: ARX_SHIFT ;GET ADDRESS WITHOUT 32-35
ARX_ARX AND ADMSK, ;FLUSH GARBAGE IN 0-3
SKP AD NE,RETURN2 ;AND MAKE THE TEST
.ENDIF/MODEL.B
;HERE FOR BYTE TRANSFERS
=000
PIBYTE: FE_# AND S,#/30,CALL,J/PIBPA ;OUT... GET BP ADDR
SET DATAI,CALL,J/EBUSI ;IN ... FIRST READ THE DATA
=011 ARX_AR,AR_MQ*4,J/PIDPB ;GOT IT, GO DEPOSIT IT
=100 VMA_AR,CALL,J/PIIBP ;GO INCREMENT OUTPUT BP
SC_FE+SC,CALL,J/LDB1 ;GO LOAD BYTE FROM IT
=111 J/PIOUT ;THEN SEND BYTE
=000
PIDPB: BRX/ARX,FE_# AND S,#/30, ;HERE WITH INPUT DATA
CALL,J/PIBPA
=100 VMA_AR+1,CALL,J/PIIBP ;GO INCREMENT INPUT BYTE PTR
AR_BRX,SC_#-SC,#/36., ;STORE BYTE WITH IT
SKP SCAD0,CALL,J/DPB1
=111 J/PIDONE
PIBPA: AR0-8_FE+#,#/140,J/GTAR08
=00*
PIIBP: CALL,J/PILD ;GET POINTER FROM EPT
P_P-S,SKP SCAD0,CALL.M,J/IBPS ;INCREMENT IT
=11* ARX_AR,SC_P,J/BYTEA ;NOW EVALUATE ITS ADDR
.TOC "KL-MODE PAGE REFILL LOGIC"
.IF/KLPAGE
;HERE ON ANY PAGE FAILURE
;THE POSSIBLE CAUSES ARE --
; 1: A PARITY ERROR WAS DETECTED IN AR OR ARX FOLLOWING A READ
; REFERENCE. IN THIS CASE WE SAVE THE BAD WORD IN A RESERVED
; LOCATION IN FAST MEMORY BLOCK 7, AND RETURN A PAGE FAIL CODE
; INDICATING THE ERROR.
; 2: THE MBOX DETECTED A PROPRIETARY VIOLATION OR PAGE TABLE PARITY
; ERROR, OR THE EBOX FOUND THE SELECTED ADDRESS BREAK CONDITION.
; IN THIS CASE, WE RETURN THE PAGE FAIL CODE GENERATED BY THE
; MBOX (SEE PRINT PAG4).
; 3: A REFERENCE OCCURRED FOR A VIRTUAL PAGE FOR WHICH THE HARDWARE
; PAGE TABLE DIRECTORY HAD NO VALID MATCH. IN THIS CASE, WE
; WRITE THE PAGE TABLE DIRECTORY FROM THE VMA, AND CLEAR THE
; ACCESS BITS FOR ALL PAGE ENTRIES CONTROLLED BY THE SELECTED
; DIRECTORY ENTRY. WE THEN JOIN THE REFILL CODE, BELOW.
; 4: A REFERENCE OCCURRED FOR A VIRTUAL PAGE FOR WHICH THE ACCESS BIT
; IN THE HARDWARE PAGE TABLE WAS OFF, OR A WRITE OCCURRED TO A
; PAGE WHOSE WRITABLE BIT WAS OFF. IN THIS CASE, WE EVALUATE THE
; PAGING POINTERS IN CORE TO DETERMINE WHETHER THE ACCESS SHOULD
; BE ALLOWED, AND IF SO, THE PHYSICAL PAGE TO WHICH IT SHOULD BE
; TRANSLATED. WE THEN EITHER PAGE FAIL, OR WRITE A PAGE ENTRY
; INTO THE HARDWARE PAGE TABLE AND RESTART THE REFERENCE.
;
; [322] Note that in the latter case, if a page should be accessible
; but not writable, it is the microcode's responsibility to turn on
; bit 2 of the page fail word (the Accessible bit) if a write
; reference is attempted to such a page. Currently, this is done only
; if no CST is present (TOPS-10 operating mode), since TOPS-20
; retraces the page map from scratch and thus generates the correct
; information. The bit can be made correct for the CST present case
; (see code near NOTWR), but since we are now quite tight on control
; store, we have chosen not to implement this.
;
; If you are looking at this code for the first time, be aware that
; only AR, ARX, SC, and FE are saved and restored here; thus BRX and
; MQ are strictly off limits for this code.
;
.IFNOT/MODEL.B
2377: CLR ACCOUNT EN,FORCE AR-ARX,J/PF1
.IF/MODEL.B
3777: CLR ACCOUNT EN,FORCE AR-ARX,J/PF1
.ENDIF/MODEL.B
1777: CLR ACCOUNT EN,FORCE AR-ARX
PF1: SV.AR_AR,AR_ARX,ARX_AR (AD) ;SAVE CURRENT AR
SV.ARX_AR,AR_ARX,ARX_AR (AD) ; AND ARX
.IF/PAGCNT ;[327] Page fault counting
AR_TRX2+1 ;[327] Count this page fault
TRX2_AR
AR_SV.AR ;[346] Don't lose initial AR
.ENDIF/PAGCNT ;[327]
GET ECL EBUS,PF DISP,J/PF2 ;PARITY ERROR?
=1100
PF2:
.IFNOT/PAGCNT ;[327]
=1101 FE_#,#/36,SKP RPW,J/PFPAR ;YES. AR PARITY ERROR, CODE 36
;CHECK FOR MIDDLE OF RPW CYCLE
.IF/PAGCNT
=1101 AR_SV.AR,J/ARPAR ;[327] AR parity error. Get back
.ENDIF/PAGCNT ;[327] saved AR
AR_ARX,FE_#,#/37,SKP RPW,J/PFPAR;[307] YES, ARX PARITY. COULD BE RPW
AR_EBUS REG,MB WAIT ;NO. GET PAGE FAIL WORD
REL ECL EBUS,PF DISP,J/PF4 ;EBOX HANDLING REQUIRED?
;
.IF/PAGCNT ;[327]
ARPAR: FE_#,#/36,SKP RPW,J/PFPAR ;Set code 36 and check for RPW
.ENDIF/PAGCNT
;HERE ON ANY PARITY ERROR
;SKIP IF MIDDLE OF READ-PAUSE-WRITE CYCLE, IN WHICH CASE WE
; MUST WRITEBACK THE DATA TO PREVENT INCOMPLETE CYCLE
=0
PFPAR: VMA_VMA HELD,J/PFPAR1 ;MAY HAVE CHANGED AT MBWAIT
STORE ;WRITEBACK WITH GOOD PARITY
PFPAR1: MAP,SC_#,#/140 ;GET MAP INFO ON REF
PFPAR2: SV.PAR_AR,MB WAIT ;[234]SAVE WORD WITH BAD PARITY
AR_EBUS REG ;READ MAP INFO
REL ECL EBUS,SC_P AND SC ;GET USER BIT FROM MAP WORD
P_FE OR SC,J/PF4 ;STUFF IN PARITY ERROR CODE
;HERE WITH PAGE FAIL WORD IN AR
; TESTING FOR EBOX HANDLING REQUIRED.
=0111
PF4: SV.PFW_AR,SR DISP,J/CLEAN ;NO, GO CLEAN UP
SV.PFW_AR,AR_BR,BR/AR ;YES, GET BR TOO
SV.BR_AR,AR_0S ;SAVE BR
AR0-8_FE ;NOW SAVE 10-BIT REGS
ARX_AR (AD),AR0-8_SC ;FE TO ARX, SC TO AR
ARR_ARL,ARL_ARX (ADX), ;FE IN ARL, SC IN ARR
ARX_VMA HELD ;GET VMA WHICH FAILED
SV.SC_AR,AR_ARX, ;HOLD SC & FE
GEN BR*2,SIGNS DISP ;TEST FOR PT DIR MATCH
=1110
PGRF1: SV.VMA_AR,ARX_AR SWAP,ARR_ARL, ;GET SEC # TO AR32-35
DISP/EA MOD,J/PGRF2 ; SEC < 20?
; HERE TO WRITE PT DIR, & CLR 4 PAGE ENTRIES. If the expanded
; page table ECO has been installed, this will only clear two entries
; (since they go in pairs for that case), but in either case the
; right thing will happen. [333]
;
AR_0S,COND/MBOX CTL,MBOX CTL/2, ;READY TO CLEAR EVEN PAIR
FE_P AND #,#/2,SC/SCAD ;GET WRITE REF BIT TO FE & SC
COND/MBOX CTL,MBOX CTL/33, ;CLR EVEN, WR DIR, SEL ODD
TIME/3T,FE_FE+SC,SC/SCAD; WR REF = 4 NOW
COND/MBOX CTL,MBOX CTL/10, ;CLR ODD, RESET NORMAL SELECT
TIME/3T,FE_FE+SC,AR_BR ;GET PFW BACK, WR REF = 10
SC_# AND AR0-8,#/401 ;GET USER & PAGED REF BITS
AR0-8_FE OR SC ;COMBINE WITH WR REF BIT
SV.PFW_AR,BR/AR,AR_ARX,J/PGRF1 ;REJOIN MAIN PATH
; HERE TO TRACE PAGE POINTERS FOR THIS ADDRESS
; VMA WHICH FAILED IS IN ARX AND AR WITH THE HALVES SWAPPED
; PAGE FAIL WORD IS IN BR
; [333] Bit 5 of all access pointers is implemented as "Keep" for
; pages which should not be swept from the page map on DATAO PAG
; UBR reload unless bit 3 is also set.
;
.IFNOT/EPT540
=1101
PGRF2: VMA_#+AR32-35,#/440, ;YES.
SIGNS DISP,J/PGRF3 ; USER REF?
VMA_#+AR32-35,#/460, ;NO
SIGNS DISP,J/PGRF3
.IF/EPT540
=1101
PGRF2: VMA_#+AR32-35,#/540, ;YES.
SIGNS DISP,J/PGRF3 ; USER REF?
VMA_#+AR32-35,#/560, ;NO
SIGNS DISP,J/PGRF3
.ENDIF/EPT540
=1101
PGRF3: LOAD AR,EPT REF,FE_-1,J/SECPTR ;Initialize APWKC bits, get section
LOAD AR,UPT REF,FE_-1 ; pointer from EPT or UPT
;HERE TO FIND PAGE MAP WITH SECTION POINTER
SECPTR: AR_MEM,SC_#,#/9,SKP INTRPT ;GET SECTION POINTER
=1000 FE_FE AND AR0-8,BR/AR, ;COMBINE ACCESS BITS
AR0-3 DISP ;SPT INDEX IN ARR, DISP ON TYPE
=1001 AR_SV.BR,J/PFT ;NO ACCESS TO SECTION (OR INTRPT)
=1011
SECIMM: ARX_SHIFT,ARL_0.M,J/PGRF5 ;IMMEDIATE
=1101 ARL_0.M,J/LDIND ;SHARED
=1111 ARL_0.M ;INDIRECT SECTION POINTER
;
; WARNING: do not use the technique at LDIND to allow
; interrupts out of section pointer loops, as that will have
; adverse effects on byte transfers and console executes.
;
VMA_AR+SBR,AR_ARX ;LOOK IN SPT
BR/AR,AR_BR,LOAD AR,PHYS REF ;CALL FOR SPT ENTRY
ARX_SHIFT,AR_MEM ;SEC PTR INDEX TO ARX0-8
AR_SHIFT,ARX_BR ;NEW SEC PTR ADDR TO AR
GEN # AND AR0-8,#/77,SKP SCAD NE,
VMA_AR
=0 LOAD AR,PHYS REF,J/SECPTR
AR_SV.BR,J/PFT ;TRAP, SEC MAP NOT IN CORE
;
; We must turn off special cycle for indirect pointers so that
; we can take an interrupt. However, we can't do it if PXCT or
; SXCT might be active. Thus, a kernel mode program can get into
; a page fail loop that the microcode cannot exit.
;
=0
LDIND: VMA_AR+SBR,J/LDIND1 ;FOR INDIRECT PAGE POINTERS
CLR SPECIAL CYCLE,J/LDIND
;
; This fixes the glitch that INSTR FETCH (NICOND) doesn't
; clear 'CON4 INT DISABLE L' before fetching user's instruction.
; ;SHARED SEC = INDRCT PAG
LDIND1: LOAD AR,PHYS REF ;GET PAGE MAP ADDR
AR_MEM,J/SECIMM
;HERE WITH PAGE NO OF PAGE MAP IN AR,
; VIRTUAL PAGE NO WITHIN SECTION IN ARX0-8
.IF/NOCST
PGRF5: TEST CBR ;[247] CBR = 0 MEANS NO CST UPDATE
.IF/BIG.PT ;[346]
=0 AR_ARX,FE_FE AND #,#/174, ;[247][333] NO CST UPDATE
J/NO.CST ;[247]
.IFNOT/BIG.PT ;[346]
=0 AR_ARX,FE_FE AND #,#/164, ;[247] NO CST UPDATE. Eat bit 5
J/NO.CST ;[247] if no big page table
.ENDIF/BIG.PT ;[346]
.IFNOT/NOCST ;[247]
PGRF5:
.ENDIF/NOCST ;[247]
VMA_AR+CBR,AR_ARX ;GENERATE CST ADDRESS
GEN # AND AR0-8,#/77, ;IS PAGE MAP IN CORE?
SKP SCAD NE
=0 LOAD AR,PHYS REF, ;GET CST ENTRY FOR PAGE MAP
BR/AR,J/PGRF6 ;SAVE PAGE PTR ADDR IN BR
AR_SV.BR,J/PFT ;NOT IN CORE, PAGE FAIL TRAP
;
.IF/BIG.PT ;[346]
PGRF6: AR_MEM,FE_FE AND #,#/174 ;[333]HERE IF CST FOR PAGE MAP
.IFNOT/BIG.PT ;[346]
PGRF6: AR_MEM,FE_FE AND #,#/164 ;HERE IF CST FOR PAGE MAP. No K bit
.ENDIF/BIG.PT ;[346] if no big page table
AR_AR AND CSMSK,SKP P NE ;BEGIN CST UPDATE
=0 AR_SV.BR,J/PFT ;AGE TRAP, MAP BEING SWAPPED
AR_AR OR PUR,STORE ;PUT CST WORD BACK
.IFNOT/NOCST ;[247]
MEM_AR,VMA_BR,PHYS REF ;PHYS REF MAKES MODEL.A LOAD
;LONG VMA
LOAD AR,PHYS REF ;GET PAGE MAP ENTRY
AR_MEM,FE_FE OR #,#/100, ;PAGE POINTER
SKP INTRPT ;CHECK FOR LONG INDIRECT
;POINTER
.IF/NOCST ;[247]
MEM_AR,VMA_BR,PHYS REF,J/NOCST0 ;PHYS REF MAKES MODEL.A LOAD
;LONG VMA
NO.CST: GEN # AND AR0-8, #/77, ;[247] page map in core ?
VMA_AR,SKP SCAD NE ;[247]
=0
NOCST0: LOAD AR,PHYS REF, J/NOCST1 ;[247] GET PAGE MAP ENTRY
AR_SV.BR, J/PFT ;[247] not in core, pf trap
NOCST1: AR_MEM,FE_FE OR #,#/100, ;[247] PAGE POINTER
SKP INTRPT ;[247] CHECK FOR LONG INDIRECT
.ENDIF/NOCST ;[247] POINTER
;
; HERE WITH PAGE MAP ENTRY IN AR
; FE HAS ACCUMULATED ACCESS BITS -- APWKC*4
; SC CONTAINS 9.
;
=1000 FE_FE AND AR0-8,AR0-3 DISP, ;COMBINE PWKC, DISP ON TYPE
ARX_SV.VMA,TIME/3T ;[346] GET BACK SAVED VMA
=1001 AR_SV.BR,J/PFT ;0=NO ACCESS (OR HERE ON INTRPT)
=1011
LDIMM: ARL_SHIFT,FE_FE SHRT, ;1=IMMEDIATE, LOAD PT
ARX_ARX*2 COMP, ; GET -WR REF TO ARX03
SC_#,#/4,J/LDPT ;[333] Set to move K bit
=1101 ARL_0.M,J/LDSHR ;2=SHARED, GET SPT ENTRY
=1111 ARL_0.M,ARX_SHIFT,SKP USER, ;3=INDIRECT, LOOP
J/LDIND
;
; HERE TO GET SHARED PAGE POINTER OUT OF SPT
;
LDSHR: VMA_AR+SBR ;ADDRESS OF SPT ENTRY
LOAD AR,PHYS REF
AR_MEM,FE_FE OR #,#/100,J/LDIMM ;TREAT SPT ENTRY AS IMMED
;
; HERE WITH IMMEDIATE PAGE NO IN AR TO LOAD INTO PT
;
LDPT: GEN # AND AR0-8,#/77,SKP SCAD NE;Test storage medium
.IF/BIG.PT ;[333]
=0 ARL_0.M,GEN FE AND SC, ;[333]In core. Is Keep bit set?
SKP SCAD NE,J/LDPT1
.IFNOT/BIG.PT
=0 ARL_0S,J/LDPT1
.ENDIF/BIG.PT ;[333]
AR_SV.BR,J/PFT ;PAGE NOT IN CORE
;
.IF/BIG.PT ;[333]
=0
.ENDIF/BIG.PT
LDPT1: ARX_AR,AR_ARX*.25,SC_1,J/KMOVED ;[333]No K. GET -WR REF TO AR05
.IF/BIG.PT
AR0-8_#,#/10,FE_FE-SC,J/LDPT1 ;[333]K set. Move to bit 5 for now
.ENDIF/BIG.PT
;
.IF/NOCST ;[247]
KMOVED: TEST CBR, SC_P AND SC ;[247][333]CBR = 0? (-WR REF TO SC)
=0 SC_-SC,AR_ARX,ARX_AR (AD),
J/NOUPDT ;[247] YES, SKIP SOME
.IFNOT/NOCST ;[333]
KMOVED: ;[333]
.ENDIF/NOCST ;[247]
VMA_ARX+CBR,AR_ARX,SC_P AND SC ;PAGE IN CORE. SC_-WR REF
;
; NOW GET CST ENTRY FOR THIS PAGE.
;
GTCST: LOAD AR,PHYS REF,ARX_AR SWAP, ;Shuffle K over to bit 23
SC_-SC,AR_1 ;SC=0 IF WR REF, ELSE -1
GEN FE AND #,#/10,SKP SCAD NE, ;SKIP IF WRITABLE
BR/AR,MB WAIT ;GET CST ENTRY & BIT FOR TESTING
=0 GEN P AND SC,SKP SCAD NE, ;FAIL IF WRITING OR AGE=0
AR_AR AND CSMSK,J/NOTWR ;STRIP OLD AGE FROM CST
;
; [303] Looks like it's writable. Make one final check by looking
; at bit 18 of the CST entry, and abort if it's not set.
;
TEST AR.BR,SKP CRY0, ;POSSIBLY WRITABLE--SKIP IF CST
GEN #-SC,#/-1,BYTE DISP ; WRITTEN OR THIS IS WRITE REF
=110 FE_FE-#,#/4,J/STCST ;[305] TEMPORARILY UNWRITABLE, SET S
.IF/CST.WRITE ;[314]
AR_AR*BR,AD/OR,FE_FE OR #,#/4, ;SET CST WRITTEN AND SOFT BITS
SKP AR18 ;IS IT REALLY WRITABLE? [303]
=0 AR_SV.BR,J/PFT ;NOT REALLY. BAIL OUT
.IFNOT/CST.WRITE ;[314]
AR_AR*BR,AD/OR,FE_FE OR #,#/4 ;[314] Set CST written and soft bits
.ENDIF/CST.WRITE ;[314]
STCST: AR_AR AND CSMSK,SKP P NE ;[305] WRITABLE. CLEAR, TEST OLD AGE
;
; [322] At this point we should check whether we got here as a result
; of an age trap (in which case we just take the page failure) or not,
; in which case the failure was due to a write reference and we should
; set bit 2 (the A bit) in the PFW. This is not currently done
; because (1) nobody needs it now, and (2) we are very short on CRAM
; space.
;
=0
NOTWR: AR_SV.BR,J/PFT ;WRITE OR AGE TRAP
.IFNOT/NOCST ;[247]
AR_AR OR PUR,STORE ;SET USE BITS, STORE BACK CST
MB WAIT,VMA_SV.VMA, ;RELOAD VMA FOR ORIGINAL REF
AR_SV.VMA,SC_1 ;READY TO TEST VMA USER
GEN P AND SC,SKP SCAD NE, ;TEST VMA USER, copy page # to ARL,
AR_ARX, ;[333] K to AR bit 23, APMWC0 TO SC
SC_FE,ARX_AR (AD) ; MAP BIT TO ARX
=0 P_P OR SC#,EXEC REF,J/WRHPT ;BUILD PT ENTRY, CLEAR VMA USER
P_P OR SC#,USER REF ; OR SET USER, AS NECESSARY
WRHPT: WR PT ENTRY,FE_#,#/10,AR_ARX*4 ;UPDATE HARDWARE TABLE
.IF/NOCST
AR_AR OR PUR,STORE,J/WRHPT ;[247]SET USE BITS,
; STORE BACK CST
;
NOUPDT: GEN FE AND #, #/10, ARX_AR SWAP,
AR_ARX (AD),SKP SCAD NE ;[247] SKIP IF WRITABLE
=0 AR_SV.PFW,GEN P AND SC, ;[322] Get saved PFW and
SKP SCAD NE,J/NOT.WR ;[247]FAIL IF WRITING
FE_FE OR #, #/4, J/WRHPT ;[247]SET WRITABLE BIT
;
WRFAIL: SV.PFW_AR,J/NOTWR ;[322]Restore PFW and page fail
;
=0 ;[323]
NOT.WR: AR0-8_# OR AR0-8,#/100,J/WRFAIL ;[322]Write failure. Set A in PFW
WRHPT: RSTR VMA_SV.VMA,AR_ARX,SC_FE ;RELOAD ORIGINAL VMA
P_P OR SC ;[333]COMBINE APMWC WITH PAGE #, K
WR PT ENTRY ;UPDATE HARDWARE PAGE TABLE
.ENDIF/NOCST
;HERE WHEN MAP INFO WRITTEN INTO HARDWARE PAGE TABLE
; WE NOW NEED ONLY RESTORE THE REGISTERS WE HAVE USED, AND RESTART THE
; MEMORY REFERENCE WHICH FAILED, RETURNING TO THE MICROINSTRUCTION
; WHICH WAITS FOR ITS COMPLETION. (EXCEPT FOR MAP)
.IFNOT/MODEL.B
GEN FE AND S,SKP SCAD NE, ;TEST FOR MAP INSTR
AR_SV.SC
.IF/MODEL.B
AR_SV.SC
.ENDIF/MODEL.B
;HERE TO RESTORE REGISTERS AND RESTART REFERENCE WHICH FAILED
=0 SC_EXP,FE_EXP,SKP AR0, ;RESTORE FE
AR_AR SWAP,ARX_SV.BR,J/PGRST1
.IFNOT/MODEL.B
AR_SV.VMA,ARX_SV.VMA,J/COMPEA ;*MAP* RESTART FROM AREAD
.IF/MODEL.B
=
.ENDIF/MODEL.B
=0
PGRST1: SC_EXP,SKP AR0, ;RESTORE SC
AR_ARX,ARX_SV.AR,J/PGRST2
FE_-SC-1,J/PGRST1 ;MAKE FE NEG
=0
PGRST2: BR/AR,AR_ARX, ;RESTORE BR AND AR
ARX_SV.ARX,J/PGRST3 ; AND ARX
SC_-SC-1,BR/AR,AR_ARX, ;NEGATE SC
ARX_SV.ARX
;HERE RETURN TO POINT OF FAULT. THERE MUST BE EXACTLY ONE MICRO-
; INSTRUCTION, OF 2 OR 3 TICKS, BETWEEN THE REQUEST AND THE RETURN.
; AT LEAST ONE IS REQUIRED TO GET NICOND LOGIC SET UP CORRECTLY IN
; CASE THIS IS A FETCH, BUT THERE MUST NOT BE TIME FOR A READ TO
; READ REFERENCE TO COMPLETE, BECAUSE THE MB WAIT INSTRUCTION TO WHICH
; WE RETURN MAY EXPECT TO GET SOMETHING OUT OF AR OR ARX BEFORE THE
; MBOX RESPONSE. SEE DPB1.
PGRST3: REQ SV.VMA ;RESTART FAULTED REQUEST
SET ACCOUNT EN,RETURN0 ;RETURN TO POINT OF FAILURE
;HERE ON A TRAP CONDITION DETECTED BY REFILL LOGIC
;AR CONTAINS SAVED BR
PFT: BR/AR,VMA_SV.VMA, ;RESTORE BR & VMA
SR DISP,J/CLEAN ;TAKE TRAP
.TOC "KI-MODE PAGE FAIL HANDLING"
.IFNOT/KLPAGE
.IFNOT/MODEL.B
2377: CLR ACCOUNT EN,FORCE AR-ARX,J/PFSAVE
.IF/MODEL.B
3777: CLR ACCOUNT EN,FORCE AR-ARX,J/PFSAVE
.ENDIF/MODEL.B
1777: CLR ACCOUNT EN,FORCE AR-ARX ;DON'T CHARGE PAGE FAIL TO USER
PFSAVE: SV.AR_AR,AR_ARX ;PRESERVE AR, ARX
SV.ARX_AR,SR DISP,J/CLEAN ;NOW CHECK FOR CLEANUP REQUIRED
.ENDIF/KLPAGE
;HERE ON PAGE FAIL OR INTERRUPT WHICH REQUIRES CLEANUP IN ORDER
; TO BE CORRECTLY RESTARTABLE AFTER SERVICE...
=1*0000
CLEAN: FE_#,#/37,SKP INTRPT,J/PGF1 ;HERE FOR INTRPT OR PGF?
;(1) HERE ON EDIT SOURCE FAIL
AR_SRCP,SR_0,J/BACKS ;BACK UP SRC POINTER
;(2) HERE ON ANY FAILURE IN DECIMAL TO BINARY
AR_BR LONG,SR_1,J/D2BPF ;GET ACCUMULATED BINARY
;(3) HERE ON DST FAIL IN BINARY TO DECIMAL FILL
AR_DLEN COMP,SR_#,#/4,J/B2DFPF
;(4) HERE ON EDIT DST FAIL WITH NO SRC POINTER UPDATE
SR_0,J/BACKD ;BACK UP DST POINTER ONLY
;(5) HERE ON EDIT DST FAIL AFTER UPDATING SRC POINTER
SR_1,J/BACKD ;BACK UP DST, THEN SRC
;(6) HERE ON DESTINATION FAILURE IN BINARY TO DECIMAL
SR_BDT,J/BACKD ;BACK UP DST, THEN SAVE FRACTION
;(7) HERE ON BLT FAILURE
.IF/KLPAGE
ARX_SV.ARX,J/BLTPF ;GET DEST ADDR AGAIN
.IFNOT/KLPAGE
BLTPF: AR_ARX+BR,SR_0,J/BLTPF1 ;CURRENT SRC ADDR
.ENDIF/KLPAGE
;(10) HERE ON TRANSLATION FAILURE IN BINARY TO DECIMAL
AR_BR LONG,SR_0,J/B2DPF ;GET BINARY FRACTION
;(11) HERE ON SRC FAILURE IN COMPARE OR MOVE STRING
AR_DLEN,SR_1,J/STRPF ;PUT LENGTHS BACK, THEN BACK SRC
;(12) HERE ON DST FAILURE IN COMPARE OR MOVE STRING
AR_DLEN,SR_#,#/4,J/STRPF
;(13) HERE ON DST FAILURE AFTER UPDATING SRC IN COMPARE OR MOVE
SR_SRC,J/BACKD ;BACK DST, THEN HANDLE AS SRC FAIL
;(14) HERE ON DST FILL FAILURE IN MOVRJ
AR_DLEN,SR_#,#/4,J/STRPF4
.IF/KLPAGE
;(15) HERE ON PAGE FAILURE IN MAP INSTRUCTION. RETURN PAGE FAIL WORD
AR_SV.PFW,SKP IO LEGAL,J/MAP2 ;RETURN PFW IN AC
.ENDIF/KLPAGE
.IF/XADDR
;(16) HERE ON PAGE FAIL IN XBLT
AR_BR LONG,SR_0,J/XBLTPF
.ENDIF/XADDR
.IF/MODEL.B
;(17) HERE ON FAILURE IN WORD MOVE STRING
AR_DLEN,SR_0,J/STRPF4
.ENDIF/MODEL.B
=
;HERE ON ANY PAGE FAILURE OR PI REQUEST IN LONG INSTRUCTIONS
; SKIP IF PI REQUEST, WHICH TAKES PRIORITY
.IF/KLPAGE
=0
.IFNOT/SHIFT.MUUO
PGF1: MB WAIT,VMA_#,#/500,J/PGF2
.IF/SHIFT.MUUO
PGF1: MB WAIT,VMA_#,#/501,J/PGF2 ;SHIFT TO CLOSER MATCH XADDR FORM
.ENDIF/SHIFT.MUUO
SET ACCOUNT EN,J/TAKINT ;CLEANUP DONE, SERVE INTRPT
PGF2: AR_SV.PFW,SKP PI CYCLE,J/PGF4 ;GET BACK PAGE FAIL WORD
.IFNOT/KLPAGE
=0
PGF1: GET ECL EBUS,CLR SC,
PF DISP,J/PGF2
SET ACCOUNT EN,J/TAKINT ;HERE TO SERVE INTRPT, DO IT
=1100
PGF2:
=01 AR_SV.AR,FE_FE-1, ;AR PARITY ERROR
SKP RPW,J/PGF6 ;DO WE NEED TO RESTART RPW?
=10 VMA_VMA HELD,MAP,SC_FE ;ARX PARITY ERROR, PF CODE 37
PGF3: MB WAIT,VMA_#,#/500
AR_EBUS REG ;READ PAGE FAIL WORD
REL ECL EBUS
P_P OR SC,SKP PI CYCLE ;STUFF ERROR CODE IF PARITY
.ENDIF/KLPAGE
=00
PGF4: ARX_AR,AR_VMA HELD,SC_#,#/13., ;READY TO COMBINE PF WORD
CALL,J/ROTS ; WITH ADDRESS
ARX_AR,AR_VMA HELD,SC_#,#/13., ;READY TO COMBINE PF WORD
J/IOPGF ; WITH ADDRESS
=11 AR_SHIFT,ABORT INSTR ;RECOVER TRAP FLAGS, IF ANY
.IFNOT/XADDR
STORE,UPT REF ;PUT PAGE FAIL WORD AT 500
FIN STORE,AR_PC,
VMA_VMA+1,STORE ;STORE OLD PC AT 501 OR 502
FIN STORE,AR_0S,
VMA_VMA+1,LOAD AR ;GET NEW PC FROM 502 OR 503
SET ACCOUNT EN,J/NEWPC
.IF/XADDR
STORE,UPT REF,ARX_PC ;PAGE FAULT WORD TO 500
AR_ARX ANDC ADMSK,MB WAIT, ;GET PC FLAGS FOR STORING
BRX/ARX,ARX/AD ;FULL PC IN BRX, FLAGS IN ARX
AR_0.S,SKP USER
=0 AR12-17_PREV SEC,CALL [ARSWAP] ;[334] GET PCS IF EXEC MODE
ARL_ARXL,ARR_ARR, ;FLAGS WORD IN AR
VMA_VMA+1,STORE ;STORE FLAGS WORD IN 501
AR_ARX*BRX,AD/ANDCA, ;GET PC ADDRESS
VMA_VMA+1,STORE ; STORE IT IN 502
AR_0S,VMA_VMA+1,LOAD AR ;GET NEW PC ADDRESS FROM 503
SET FLAGS_AR ;CLEAR ALL FLAGS
AR_MEM,SET ACCOUNT EN,J/ARJMP ;NEW ADDRESS FOR PC
.ENDIF/XADDR
.IFNOT/KLPAGE
;HERE ON PARITY ERROR IN AR. SKIP IF READ-PAUSE-WRITE IN PROGRESS
=0
PGF6: VMA_VMA HELD,MAP, ;AR PARITY ERROR
SC_FE,J/PGF3 ;PF CODE 36
STORE,J/PGF6 ;COMPLETE CYCLE, WITH GOOD PAR
.ENDIF/KLPAGE
.TOC "PAGE FAIL/INTERRUPT CLEANUP FOR SPECIAL INSTRUCTIONS"
;HERE ON PAGE FAIL DURING PI CYCLE
.IFNOT/MODEL.B ;[224][274]
IOPGF: AR_SHIFT,ARX_SHIFT,SC_#-SC, ;TROUBLE... CREATE PAGE FAIL WORD
#/36.
AR_SHIFT,SET IO PF
SV.IOPF_AR,J/IOPFIN ;FINISH IOPF ROUTINE
.IF/MODEL.B ;[224] DO FANCY STUFF FOR DTE.
IOPGF: AR_FM[SV.IOP] ;[274] GET THE SAVED API WORD
SV.IOPF_AR ;[224] SAVE IT IN AC BLK 7.
BR/AR,AR_SV.AR ;[224] KEEP IOPF WORD AROUND,
SET IO PF ;[224][274] HANDLE DTE.
;[223] THIS RESTARTS THE DTE'S CLOCK TO PREVENT A DEX FAILURE.
=10 SET DATAO,CALL,J/EBUSO ;[223] SEND THE DATA TO THE DTE.
AR_BR,SET ACCOUNT EN,J/PIDONE ;[223] AND FINISH THE INTRPT.
.ENDIF/MODEL.B ;[224]
;HERE ON BLT PAGE FAIL
.IF/KLPAGE
BLTPF: AR_ARX+BR,SR_0 ;CURRENT SRC ADDR
.ENDIF/KLPAGE
BLTPF1: AR_ARX (AD),ARL_ARR
PGFAC0: AC0_AR,SR DISP,J/CLEAN ;BEGIN NORMAL PF WORK
;HERE ON XBLT PAGE FAIL OR INTERRUPT
.IF/XADDR
XBLTPF: AC1_AR,AR_ARX
AC2_AR,J/CLEAN
.ENDIF/XADDR
;HERE ON VARIOUS CASES OF STRING/EDIT FAILURE
BACKS: P_P+S
SRCP_AR,SR DISP,J/CLEAN ;RE-DISPATCH FOR MORE
BACKD: AR_DSTP
.IF/MODEL.B
P_P+S.C,SEL DSTP ;PRESEL NUM FIELD FOR HARDW GLITCH
.IFNOT/MODEL.B
P_P+S
.ENDIF/MODEL.B
DSTP_AR,SR DISP,J/CLEAN
D2BPF: AC3_AR,AR_0S,SC_#,#/35. ;PUT AWAY HIGH BINARY
AR_SHIFT,ARX_-SLEN ;LOW TO AR, REMAINING LEN TO ARX
.IF/MODEL.B
SEL DSTP ;PRESEL NUM FIELD FOR HARDW GLITCH
.ENDIF/MODEL.B
AC4_AR,AR_ARX,J/STRPF2 ;PUT LOW AWAY
B2DFPF: AR_AR*T0,AD/OR,J/B2DPF2
B2DPF: AC0_AR,AR_ARX ;HIGH FRACTION TO AC
AC1_AR ;LOW TO AC1
AR_AC3 ;GET FLAGS
B2DPF2: AR_AR*SLEN,AD/A-B,J/STRPF3 ;REBUILD FLAGS+LEN
STRPF: BR/AR,AR_-SLEN,SKP AR0 ;WHICH IS LONGER?
=0
STRPF1: AC3_AR,AR_AR+BR,J/STRPF2 ;SRC LONGER
ARX_AR,AR_AR*SFLGS,AD/OR ;DST. BUILD SRC LEN+FLAGS
AC0_AR,AR_ARX-BR ;THAT'S AWAY, MAKE DST LEN
STRPF3: AC3_AR,SR DISP,J/CLEAN ;OK, NOW BACK UP SRC IF REQ'D
STRPF2: AR_AR*SFLGS,AD/OR,J/PGFAC0
STRPF4: BR/AR,AR_SLEN COMP,SKP AR0,J/STRPF1