Google
 

Trailing-Edge - PDP-10 Archives - BB-JF16A-SB_1986 - inout.mic
There is 1 other file named inout.mic in the archive. Click here to see a list.
	.TOC	"TRAPS"

TRAP:	[ARX]_PC WITH FLAGS	;SAVE THE PC WHICH CAUSED THE
	WORK[TRAPPC]_[ARX],	; TRAP
	SKIP KERNEL		;SEE IF UBR OR EBR
=0	[AR]_[AR]+[UBR],	;ADDRESS OF INSTRUCTION
	MEM READ,		;WAIT FOR PREFETCH TO GET INTO
				; THE CACHE. MAY PAGE FAIL BUT
				; THAT IS OK
	START READ,		;START FETCH
	VMA PHYSICAL,		;ABSOLUTE ADDRESSING
	J/TRP1			;JOIN COMMON CODE

	[AR]_[AR]+[EBR],	;WE COME HERE IN EXEC MODE
	MEM READ,		;WAIT FOR PREFETCH TO GET INTO
				; THE CACHE. MAY PAGE FAIL BUT
				; THAT IS OK
	START READ,		;START FETCH
	VMA PHYSICAL,		;ABSOLUTE ADDRESSING
	J/TRP1			;JOIN COMMON CODE

TRP1:	MEM READ, [HR]_MEM,	;PLACE INSTRUCTION IN HR
	LOAD INST		;LOAD IR, XR, @
	[HR].AND.#,		;TEST TO SEE IF THIS
	#/700000, 3T,		; IS A UUO
	SKIP ADL.EQ.0
=0	CHANGE FLAGS,		;NOT A UUO
	HOLD USER/1,		;CLEAR TRAP FLAGS
	J/XCT1			;DO THE INSTRUCTION
	UUO			;DO THE UUO
	.TOC	"IO -- INTERNAL DEVICES"

	.DCODE
700:	IOT,AC DISP,	J/GRP700
	IOT,AC DISP,	J/GRP701
	.UCODE

1701:	UUO		;DATAI APR,
1702:	UUO		;BLKO APR,
1703:	UUO		;DATAO APR,
1706:	[BR]_APR, J/APRSZ ;CONSZ APR,
1707:	[BR]_APR, J/APRSO ;CONSO APR,
1710:
RDERA:	UUO		;BLKI PI,
1711:	UUO		;DATAI PI,
1712:	UUO		;BLKO PI,
1713:	UUO		;DATAO PI,
1716:	[BR]_[PI], J/CONSZ ;CONSZ PI,
1717:	[BR]_[PI], J/CONSO ;CONSO PI,

1720:
GRP701:	UUO		;BLKI PAG,
1726:	UUO		;CONSZ PAG,
1727:	UUO		;CONSO PAG,

;680I AND CACHE SWEEP STUFF
1730:	UUO
1731:	UUO
1732:	UUO
1733:	UUO
1734:	UUO
1735:	UUO
1736:	UUO
1737:	UUO

APRSO:	[BR]_[BR].AND.# CLR LH, #/7770
CONSO:	[BR].AND.[AR], SKIP ADR.EQ.0, J/SKIP

APRSZ:	[BR]_[BR].AND.# CLR LH, #/7770
136:					;STANDARD LOCATION FOR VERSION INFO,
					;ANY UWORD THAT HAS A FREE # FIELD CAN
					;BE USED.
CONSZ:	[BR].AND.[AR], SKIP ADR.EQ.0, J/DONE,
	MICROCODE RELEASE(MAJOR)/UCR,	;MAJOR VERSION #
	MICROCODE RELEASE(MINOR)/UCR	;MINOR VERSION # (FOR ID ONLY)
1700:
GRP700:
APRID:	[BR]_#,
	#/4097.
137:	[BR]_#,
	MICROCODE OPTION(INHCST)/OPT,
	MICROCODE OPTION(NOCST)/OPT,
	MICROCODE OPTION(NONSTD)/OPT,
	MICROCODE OPTION(UBABLT)/OPT,
	MICROCODE OPTION(KIPAGE)/OPT,
	MICROCODE OPTION(KLPAGE)/OPT,
	MICROCODE VERSION/UCV,
	HOLD RIGHT,
	J/RTNREG

1704:
WRAPR:	[BR]_WORK[APR]
	[BR]_[BR].AND.NOT.#,	;CLEAR THE OLD PIA
	#/7, HOLD LEFT		; ..
	[ARX]_[AR].AND.#, #/7	;PUT NEW PIA IN ARX
	[BR]_[BR].OR.[ARX]	;PUT NEW PIA IN BR
	[ARX]_[AR].AND.#, 	;MASK THE DATA BITS
	#/007760		; DOWN TO ENABLES
	TR [AR], #/100000	;WANT TO ENABLE ANY?
=0	[BR]_[BR].OR.[ARX]	;YES--SET THEM
	TR [AR], #/40000	;WANT TO DISABLE ANY?
=0	[BR]_[BR].AND.NOT.[ARX]	;YES--CLEAR THEM
	[BRX]_APR		;GET CURRENT STATUS
	TR [AR], #/20000	;WANT TO CLEAR FLAGS?
=0	[BRX]_[BRX].AND.NOT.[ARX] ;YES--CLEAR BITS
	TR [AR], #/10000	;WANT TO SET ANY FLAGS?
=0	[BRX]_[BRX].OR.[ARX]	;YES--SET FLAGS
	TR [AR], #/30000	;ANY CHANGE AT ALL?
=0	READ [BRX],		;YES--LOAD NEW FLAGS
	J/WRAPR2		;TURN OFF INTERRUPT 8080
WRAPR1:	READ [BR]		;FIX DPM TIMING BUG
	READ [BR], 		;ENABLE CONDITIONS
	SET APR ENABLES
	WORK[APR]_[BR],		;SAVE FOR RDAPR
	J/DONE			;ALL DONE

WRAPR2:	READ [BRX], 		;LOAD NEW FLAGS
	SPEC/APR FLAGS		; ..
	[BRX]_[BRX].AND.NOT.#,	;CLEAR INTERRUPT THE 8080
	#/002000, HOLD LEFT	; FLAG
	READ [BRX], 		;LOAD NEW FLAGS
	SPEC/APR FLAGS,		; ..
	J/WRAPR1		;LOOP BACK
1705:
RDAPR:	[BR]_WORK[APR]
	[BR]_[BR] SWAP,		;PUT ENABLES IN BOTH
	HOLD RIGHT		; HALVES
	[BR]_[BR].AND.#,	;SAVE ENABLES IN LH
	#/7760,			;
	HOLD RIGHT
	[BR]_[BR].AND.#,	;SAVE PIA IN RH
	#/7,
	HOLD LEFT
	[ARX]_APR		;READ THE APR FLAGS
	[ARX]_[ARX].AND.# CLR LH, ;MASK OUT JUNK
	#/007770		;KEEP 8 FLAGS
	[BR]_[BR].OR.[ARX],	;MASH THE STUFF TOGETHER
	J/RTNREG		;RETURN
.TOC	"IO -- INTERNAL DEVICES -- EBR & UBR"

	;UBR FORMAT:
	;BITS  0 & 2	LOAD FLAGS (RETURNED ON RDUBR)
	;BITS  3 - 5	ZERO
	;BITS  6 -11	AC BLOCKS SELECTED - CUR,PREV
	;BITS 16 -35	UPT PHYSICAL ADDRESS

1723:
WRUBR:	VMA_[AR],		;LOAD E INTO VMA
	START READ		;START MEMORY
	MEM READ,		;WAIT FOR DATA
	[AR]_MEM, 3T,		;PUT IT INTO THE AR
	SKIP DP0		;SEE IF WE WANT TO LOAD
				; AC BLOCK NUMBERS

=0	[AR]_[AR].AND.#,	;NO--CLEAR JUNK IN AR (ALL BUT LD UBR)
	#/100000,		; LEAVE ONLY LOAD UBR
	HOLD RIGHT,		; IN LEFT HALF
	SKIP ADL.EQ.0, 3T,	;SEE IF WE WANT TO LOAD UBR
	J/ACBSET		;SKIP AROUND UBR LOAD

	;HERE WHEN WE WANT TO LOAD AC BLOCK SELECTION
	[UBR]_[UBR].AND.#,	;MASK OUT THE UBR'S OLD
	#/770077,		; AC BLOCK NUMBERS
	HOLD RIGHT		;IN THE LEFT HALF

	[AR]_[AR].AND.#,	;CLEAR ALL BUT NEW SELECTION
	#/507700,		;AND LOAD BITS
	HOLD RIGHT		;IN AR LEFT

	[AR].AND.#,		;SEE IF WE WANT TO LOAD
	#/100000, 3T,		; UBR ALSO
	SKIP ADL.EQ.0

	;HERE WITH AR LEFT = NEW AC BLOCKS OR ZERO, 
	;SKIP IF DON'T LOAD UBR
=0
ACBSET: [BR]_[AR].AND.#,	;COPY UBR PAGE NUMBER
	#/3777,			; INTO BR
	J/SETUBR		;GO LOAD UBR

	[UBR]_[UBR].OR.[AR],	;DO NOT LOAD UBR
				; PUT AC BLOCK # IN
	HOLD RIGHT,		; THE LEFT HALF
	LOAD AC BLOCKS,		;LOAD HARDWARE
	J/DONE			;ALL DONE
	;HERE WITH AR LEFT AS BEFORE, AR RIGHT = MASKED PAGE #
SETUBR: [BR]_0, 		;CLEAR BR LEFT
	HOLD RIGHT,		;BR IS 0,,PAGE #
	SC_7			;PUT THE COUNT IN SC
=0
STUBRS: [BR]_[BR]*2,		;SHIFT BR OVER
	STEP SC,		; 9 PLACES
	J/STUBRS		;PRODUCING UPT ADDRESS

	[UBR]_[UBR].AND.#,	;MASK OUT OLD UBR
	#/777774,		; BITS IN
	HOLD RIGHT		; LEFT HALF

	[UBR]_0,		;CLEAR RIGHT HALF
	HOLD LEFT		;UBR IS FLGS+ACBLK+0,,0

	[UBR]_[UBR].OR.[BR]	;PUT IN PAGE TABLE ADDRESS

	[UBR]_[UBR].OR.[AR],	;PUT IN AC BLOCK #
	HOLD RIGHT,		; IN LEFT HALF
	LOAD AC BLOCKS,		;TELL HARDWARE
	J/SWEEP			;CLEAR CACHE
1724:
WREBR:	[AR]_[AR]*2, SC_6	;DO A SHIFT OVER 8 MORE
=0
WREBR1:	[AR]_[AR]*2, STEP SC, J/WREBR1	;SKIP WHEN = -1
.IF/FULL			;DO NOT ENABLE PAGING IN SMALL
				; MICROCODE.
	[BR]_WORK[APR]
	[BR]_[BR].AND.#, #/747777, HOLD LEFT
	[AR].AND.#, #/20, 3T, SKIP ADL.EQ.0	;BIT 22 - TRAP ENABLE
=0	[BR]_[BR].OR.#, #/030000, HOLD LEFT	;SET - ALLOW TRAPS TO HAPPEN
	READ [BR], SET APR ENABLES
	WORK[APR]_[BR]
.ENDIF/FULL

.IF/KIPAGE
.IF/KLPAGE
	[EBR]_[AR]		;NOTE: SHIFTED LEFT 9 BITS
	[EBR].AND.#, #/40, 3T, SKIP ADL.EQ.0	;BIT 21 - KL PAGING ENABLE
=0	[EBR]_[EBR].OR.#, #/400000, HOLD RIGHT, J/SWEEP ;YES, SET INTERNAL FLAG
	[EBR]_[EBR].AND.NOT.#, #/400000, HOLD RIGHT, J/SWEEP ;NO, CLR BIT 0
.ENDIF/KLPAGE
.ENDIF/KIPAGE

.IFNOT/KLPAGE			;MUST BE KI ONLY
	[EBR]_[AR],J/SWEEP	;SO INTERNAL FLAG ISN'T USED
.ENDIF/KLPAGE

.IFNOT/KIPAGE			;MUST BE KL ONLY
	[EBR]_[AR],J/SWEEP	;SO INTERNAL FLAG ISN'T USED
.ENDIF/KIPAGE

1725:
RDEBR:	[BR]_[EBR]*.5, SC_6
=0
RDEBR1:	[BR]_[BR]*.5, STEP SC, J/RDEBR1
	[BR]_[BR].AND.#, #/63777 ;MASK TO JUST EBR
	[BR]_0,			;CLEAR LEFT HALF
	HOLD RIGHT,		; BITS
	J/RTNREG		;RETURN ANSWER
1721:	
RDUBR:	[BR]_[UBR].AND.#,#/507700,HOLD RIGHT	;GET LOAD BITS AND AC BLOCKS
=0	[BRX]_[UBR]*.5, SC_6, CALL [GTPCW1]	;SET SC (9) START SHIFT,GET UBR
	VMA_[AR],START WRITE,	;START TO
	J/RTNRG1		;RETURN DATA


GETPCW:	[BR]_[UBR].AND.#,#/507700,HOLD RIGHT	;GET LOAD BITS AND AC BLOCKS
	[BRX]_[UBR]*.5, SC_6			;SET SC (9) START SHIFT

=0
GTPCW1:	[BRX]_[BRX]*.5, STEP SC, J/GTPCW1	;SHIFT UBR ADDR TO PAGE #
	[BRX]_[BRX].AND.#, #/3777		;ONLY PAGE #
	[BR]_[BRX], HOLD LEFT, RETURN [1]	;MOVE PAGE # TO RH OF RESULT
.TOC	"IO -- INTERNAL DEVICES -- KL PAGING REGISTERS"

	.DCODE
702:	IOT,AC DISP,	M,	J/GRP702
	.UCODE

1760:
GRP702:
RDSPB:	[BR]_WORK[SBR], J/RTNREG
1761:
RDCSB:	[BR]_WORK[CBR], J/RTNREG
1762:
RDPUR:	[BR]_WORK[PUR], J/RTNREG
1763:
RDCSTM:	[BR]_WORK[CSTM], J/RTNREG
1766:
RDHSB:	[BR]_WORK[HSBADR], J/RTNREG
1767:	UUO

1770:
WRSPB:	START READ,WRITE TEST,5T	;WAIT FOR (?) WRITE-TEST PF
	MEM READ, [AR]_MEM
	WORK[SBR]_[AR], J/DONE
1771:
WRCSB:	START READ,WRITE TEST,5T	;WAIT FOR (?) WRITE-TEST PF
	MEM READ, [AR]_MEM
	WORK[CBR]_[AR], J/DONE
1772:
WRPUR:	START READ,WRITE TEST,5T	;WAIT FOR (?) WRITE-TEST PF
	MEM READ, [AR]_MEM
	WORK[PUR]_[AR], J/DONE
1773:
WRCSTM:	START READ,WRITE TEST,5T	;WAIT FOR (?) WRITE-TEST PF
	MEM READ, [AR]_MEM
	WORK[CSTM]_[AR], J/DONE
1776:
WRHSB:	START READ,WRITE TEST,5T	;WAIT FOR (?) WRITE-TEST PF
	MEM READ, [AR]_MEM
	WORK[HSBADR]_[AR], J/DONE

1777:	UUO
.TOC	"IO -- INTERNAL DEVICES -- TIMER CONTROL"


				;BEGIN [123]
TICK:	[AR]_WORK[TIME1],	;GET LOW WORD
	SPEC/CLRCLK		;CLEAR CLOCK FLAG
				;END [123]
TOCK:	[BR]_0 XWD [10000]	;2^12 UNITS PER MS
	[AR]_[AR]+[BR]		;INCREMENT THE TIMER
	FIX [AR] SIGN, SKIP DP0	;SEE IF IT OVERFLOWED
=0
TOCK1:	WORK[TIME1]_[AR],	;STORE THE NEW TIME
	J/TOCK2			;SKIP OVER THE OVERFLOW CODE
	[AR]_WORK[TIME0]	 ;GET HIGH WORD
=0*	[AR]_[AR]+1,		;BUMP IT
	CALL [WRTIM1]		;STORE BACK IN RAM
	[AR]_0,			;CAUSE LOW WORD WORD
	J/TOCK1			; TO GET STORED
TOCK2:	[AR]_WORK[TTG]
	[AR]_[AR]-[BR],		;COUNT DOWN TIME TO GO
	SKIP AD.LE.0		;SEE IF IT TIMED OUT
=0
TOCK3:	WORK[TTG]_[AR],		;SAVE NEW TIME TO GO
	RETURN [2]		;ALL DONE
	[AR]_WORK[PERIOD]
	[BR]_APR		;GET CURRENT FLAGS
	[BR]_[BR].OR.#, #/40	;SET TIMER INTERRUPT FLAG
	READ [BR],		;PLACE ON DP AND
	SPEC/APR FLAGS,		; LOAD INTO HARDWARE
	J/TOCK3			;ALL DONE
.TOC	"IO -- INTERNAL DEVICES -- WRTIME & RDTIME"

1774:
WRTIME:	START READ		;FETCH WORD AT E
	MEM READ,		;WAIT FOR DATA
	[AR]_MEM		;PUT WORD IN AR
=00	VMA_[HR]+1,		;BUMP E
	START READ,		;START MEMORY
	CALL [LOADARX]		;PUT DATA IN ARX
	[ARX]_[ARX].AND.#,	;CLEAR PART HELD IN
	#/770000,		; HARDWARE COUNTER
	HOLD LEFT,  CALL [WRTIM1]
=11	WORK[TIME1]_[ARX],	;IN WORK SPACE
	J/DONE			;NEXT INSTRUCTION
=
WRTIM1:	WORK[TIME0]_[AR],	;SAVE THE NEW VALUE
	RETURN [2]

1764:
RDTIME:	[BR]_TIME		;READ THE TIME
	[ARX]_TIME		; AGAIN
	[BRX]_TIME		; AGAIN
	[BR].XOR.[ARX],		;SEE IF STABLE
	SKIP AD.EQ.0		; ..
=0	[ARX]_[BRX]		;NO THEN NEXT TRY MUST BE OK
	[BR]_WORK[TIME0]
	[ARX]_[ARX]+WORK[TIME1], ;COMBINE PARTS
	SKIP/-1 MS		;SEE IF OVERFLOW HAPPENED
=00	SPEC/CLRCLK,		;CLEAR CLOCK FLAG
	[AR]_WORK[TIME1], 2T,	;GET LOW WORD FOR TOCK
	CALL [TOCK]		;UPDATE CLOCKS
	READ [HR], LOAD VMA,	;DID NOT OVERFLOW
	START WRITE, J/RDTIM1	;STORE ANSWER
	J/RDTIME		;TRY AGAIN
=
RDTIM1:	MEM WRITE, MEM_[BR]
	VMA_[HR]+1, LOAD VMA, START WRITE
	MEM WRITE, MEM_[ARX], J/DONE
.TOC	"IO -- INTERNAL DEVICES -- WRINT & RDINT"


1775:
WRINT:	START READ
	MEM READ, [AR]_MEM
	WORK[PERIOD]_[AR]
	WORK[TTG]_[AR],
	J/DONE

1765:
RDINT:	[BR]_WORK[PERIOD],
	J/RTNREG
.TOC	"IO -- INTERNAL DEVICES -- RDPI & WRPI"

1715:
RDPI:	[BR]_[PI], J/RTNREG

1714:
WRPI:	TR [AR], PI.CLR/1
=0	[PI]_0
	TR [AR], PI.MBZ/17
=0	UUO
	[BR]_[AR].AND.#,#/177
	[BR]_[BR] SWAP, HOLD RIGHT
	TR [AR], PI.DIR/1
=0	[PI]_[PI].AND.NOT.[BR], HOLD RIGHT
	TR [AR], PI.REQ/1
=0	[PI]_[PI].OR.[BR], HOLD RIGHT
	TR [AR], PI.TSN/1
=0	[PI]_[PI].OR.#,PI.ON/1, HOLD LEFT
	TR [AR], PI.TSF/1
=0	[PI]_[PI].AND.NOT.#,PI.ON/1, HOLD LEFT
	TR [AR], PI.TCN/1
=0	[PI]_[PI].OR.[BR], HOLD LEFT
	TR [AR], PI.TCF/1
=0**0	[PI]_[PI].AND.NOT.[BR], HOLD LEFT
PIEXIT:	CALL LOAD PI
=1**1
	DONE
=

;SUBROUTINE TO LOAD PI HARDWARE
;CALL WITH:
;	CALL LOAD PI
;RETURNS 10 WITH PI HARDWARE LOADED
;
LOADPI:	[T0]_[PI] SWAP		;PUT ACTIVE CHANS IN LH
LDPI2:	[T0]_-1, HOLD LEFT	;DONT MASK RH
	[T0]_[T0].AND.[PI]	;ONLY REQUEST CHANS THAT ARE ON
	.NOT.[T0], LOAD PI,	;RELOAD HARDWARE
	 RETURN [10]		;RETURN TO CALLER
.TOC	"IO -- INTERNAL DEVICES -- SUBROUTINES"


;HERE WITH SOMETHING IN BR STORE IT @AR
RTNREG:	VMA_[AR], START WRITE
RTNRG1:	MEM WRITE, MEM_[BR], J/DONE
;CACHE SWEEP

1722:
CLRPT:	VMA_[AR],		;PUT CORRECT ADDRESS IN VMA
	LOAD PAGE TABLE		;GET SET TO WRITE PAGE TABLE
	[AR]_0			;CLEAR ENTRY
=0	[AR]_#,#/377377,	;INITIAL VMA VALUE
	CALL [SSWEEP]		;LOAD THE SC
	[BR]_#, #/1001,		;CONSTANT TO KEEP ADDING
	CLRCSH			;START TO CLEAR CACHE
	READ [AR], CLRCSH	;FIRST THING TO CLEAR
=0
CLRPTL:	[AR]_[AR]-[BR],		;UPDATE AR (AND PUT ON DP)
	CLRCSH,			;SWEEP ON NEXT STEP
	STEP SC,		;SKIP IF WE ARE DONE
	J/CLRPTL		;LOOP FOR ALL ENTRIES
	READ [AR], J/ZAPPTA	;CLEAR LAST ENTRY

=0
SWEEP:	[AR]_#,#/377377,	;INITIAL VMA VALUE
	CALL [SSWEEP]		;LOAD NUMBER OF STEPS INTO SC
	[BR]_#, #/1001,		;CONSTANT TO KEEP ADDING
	SWEEP			;START SWEEP
	READ [AR], SWEEP	;FIRST THING TO CLEAR
=0
SWEEPL:	[AR]_[AR]-[BR],		;UPDATE AR (AND PUT ON DP)
	SWEEP,			;SWEEP ON NEXT STEP
	STEP SC,		;SKIP IF WE ARE DONE
	J/SWEEPL		;LOOP FOR ALL ENTRIES
				;CLEAR LAST ENTRY AND
ZAPPTA:	WORK[PTA.U]_0		; FORGET PAGE TABLE ADDRESS
	WORK[PTA.E]_0,		;FORGET PAGE TABLE ADDRESS
	J/DONE			;ALL DONE

SSWEEP:	SC_S#, S#/375,		;NUMBER OF STEPS
	RETURN [1]		;RETURN
;WE COME HERE EITHER FROM NEXT INSTRUCTION DISPATCH OR PAGE FAIL
; LOGIC. IN ALL CASES, THE CURRENT INSTRUCTION IS CORRECTLY SETUP
; TO RESTART PROPERLY.

;FIRST SET THE CORRECT PI IN PROGRESS BIT
;	[FLG]_[FLG].OR.#,FLG.PI/1, HOLD RIGHT,
;		J/PI		;SET PI CYCLE AND PROCESS PI
=1000
PI:	AD/D, DBUS/PI NEW,	;LOOK AT NEW LEVEL
	DISP/DP LEFT, 3T,	;DISPATCH ON IT
	J/PI			;GO TO 1 OF NEXT 7 PLACES
=1001	[PI]_[PI].OR.#, #/040000, HOLD LEFT, J/PIP1
=1010	[PI]_[PI].OR.#, #/020000, HOLD LEFT, J/PIP2
=1011	[PI]_[PI].OR.#, #/010000, HOLD LEFT, J/PIP3
=1100	[PI]_[PI].OR.#, #/004000, HOLD LEFT, J/PIP4
=1101	[PI]_[PI].OR.#, #/002000, HOLD LEFT, J/PIP5
=1110	[PI]_[PI].OR.#, #/001000, HOLD LEFT, J/PIP6
=1111	[PI]_[PI].OR.#, #/000400, HOLD LEFT, J/PIP7
PIP1:	[BRX]_0 XWD [1], J/PI10	;REMEMBER WE ARE AT LEVEL 1
PIP2:	[BRX]_0 XWD [2], J/PI10	;REMEMBER WE ARE AT LEVEL 2
PIP3:	[BRX]_0 XWD [3], J/PI10	;REMEMBER WE ARE AT LEVEL 3
PIP4:	[BRX]_0 XWD [4], J/PI10	;REMEMBER WE ARE AT LEVEL 4
PIP5:	[BRX]_0 XWD [5], J/PI10	;REMEMBER WE ARE AT LEVEL 5
PIP6:	[BRX]_0 XWD [6], J/PI10	;REMEMBER WE ARE AT LEVEL 6
PIP7:	[BRX]_0 XWD [7], J/PI10	;REMEMBER WE ARE AT LEVEL 7

PI10:	[AR]_[PI].AND.# CLR LH,	;TURN OFF PI SYSTEM
	#/077577		; TILL WE ARE DONE
	.NOT.[AR], LOAD PI	;  ..
	ABORT MEM CYCLE		;NO MORE TRAPS
=0	[AR]_VMA IO READ,	;SETUP TO READ WRU BITS
	WRU CYCLE/1,		; ..
	CALL [STRTIO]		;START THE CYCLE
	MEM READ,		;WAIT FOR DATA
	[AR]_IO DATA, 3T,	;PUT DATA IN AR
	SKIP ADR.EQ.0		;SEE IF ANYONE THERE
=0	[ARX]_0, J/VECINT	;YES--VECTORED INTERRUPT
	[AR]_[BRX]*2		;N*2
	[AR]_[AR]+#, #/40, 3T,	;2*N+40
	HOLD LEFT		; ..
	[AR]_[AR]+[EBR],	;ABSOULTE ADDRESS OF 
	J/PI40			; INTERRUPT INSTRUCTION
;HERE WITH ABSOLUTE ADDRESS OF INTERRUPT INSTRUCTION IN [AR]
PI40:	VMA_[AR], VMA PHYSICAL READ	;FETCH THE INSTRUCTION
PI50:	MEM READ, [AR]_MEM, LOAD VMA,	;FETCH INSTRUCTION
	3T, FORCE EXEC			;E IS EXEC MODE
	[AR].XOR.#, #/254340, 3T, SKIP ADL.EQ.0
=0	[AR].XOR.#, #/264000, SKIP ADL.EQ.0, 3T, J/PIJSR
	[BR]_FLAGS			;SAVE FLAGS
	AD/ZERO, LOAD FLAGS,
	J/PIXPCW			;ENTER EXEC MODE AND ASSUME
					; WE HAVE AN XPCW
;IF WE HALT HERE ON A VECTORED INTERRUPT, WE HAVE
;	T0/ WHAT WE READ FROM BUS AS VECTOR
;	ARX/ EPT+100+DEVICE
;	BR/  ADDRESS OF ILLEGAL INSTRUCTION
;	BRX/ VECTOR (MASKED AND SHIFTED)
=0
PIJSR:	HALT [ILLII]			;NOT A JSR OR XPCW
	START WRITE, FORCE EXEC		;PREPARE TO STORE OLD PC
=0*0	[BR]_PC WITH FLAGS,		;OLD PC
	CALL [STOBR]			;STORE OLD PC
=1*0	[AR]_#, #/0, HOLD RIGHT,		;PREPARE TO CLEAR FLAGS
	CALL [INCAR]			;BUMP POINTER
=1*1	[PC]_[AR], LOAD FLAGS,		;NEW PC
	J/PISET				;CLEAR PI CYCLE & START
					; INTERRUPT PROGRAM
=
;HERE TO PROCESS A VECTORED INTERRUPT. AT THIS POINT:
;	AR/ WRU BITS (BIT 18 FOR DEVICE 0)
;	ARX/ 0
VECINT:	[AR]_[AR]*2,		;SHIFT LEFT (UNSHIFTED ON DP)
	SKIP DP18		;ANYONE THERE?
=0	[ARX]_[ARX]+[XWD1],	;NO--BUMP BOTH HALVES
	J/VECINT		;KEEP LOOKING
	[AR]_VMA IO READ,	;SETUP FOR VECTOR CYCLE
	VECTOR CYCLE/1		; ..
=0	[AR]_[AR].OR.[ARX],	;PUT IN UNIT NUMBER
	CALL [STRTIO]		;START CYCLE
	MEM READ,		;WAIT FOR VECTOR (SEE DPM5)
	[T0]_IO DATA		;GET VECTOR
=0	[BR]_[EBR]+#, 3T, #/100,	;EPT+100
	CALL [CLARXL]		;CLEAR ARX LEFT
	[ARX]_[ARX]+[BR],	;EPT+100+DEVICE
	VMA PHYSICAL READ	;FETCH WORD
	MEM READ, [BR]_MEM, 3T,	;GET POINTER
	SKIP ADR.EQ.0		;SEE IF NON-ZERO
=0	[BRX]_([T0].AND.#)*.5, 3T, ;OK--MAKE VECTOR MOD 400
	#/774, J/VECIN1		; AND SHIFT OVER
	HALT [ILLINT]
VECIN1:	[BRX]_[BRX]*.5		;SHIFT 1 MORE PLACE
	[BR]_[BR]+[BRX],	;ADDRESS OF WORD TO USE
	LOAD VMA, FORCE EXEC,	;FORCE EXEC VIRTUAL ADDRESS
	START READ, J/PI50	;GO GET INSTRUCTION
.TOC	"PRIORITY INTERRUPTS -- DISMISS SUBROUTINE"

;SUBROUTINE TO DISMISS THE HIGHEST PI IN PROGRESS
;RETURNS 4 ALWAYS

;DISMISS:
;	TR [PI], #/077400	;ANY PI IN PROGRESS?
=0
JEN1:	[BR]_#, PI.IP1/1, J/DSMS1 ;YES--START LOOP
	RETURN [4]		;NO--JUST RETURN

DSMS1:	[PI].AND.[BR], SKIP ADR.EQ.0
=0	[PI]_[PI].AND.NOT.[BR], HOLD LEFT, RETURN [4]
	[BR]_[BR]*.5, J/DSMS1
.TOC	"EXTERNAL IO INSTRUCTIONS"

	.DCODE
710:	IOT,	WORD-TNE,	J/TIOX
711:	IOT,	WORD-TNN,	J/TIOX
720:	IOT,	TNE,		J/TIOX
721:	IOT,	TNN,		J/TIOX
	.UCODE

1614:
TIOX:	CALL [IORD]
1617:	[BR]_[AR].AND.AC, TEST DISP

	.DCODE
712:	IOT,	B/10,		J/RDIO
713:	IOT,	B/10,		J/WRIO
722:	IOT,	B/0,		J/RDIO
723:	IOT,	B/0,		J/WRIO
	.UCODE

1460:
RDIO:	CALL [IORD]
1463:	AC_[AR], J/DONE

1461:
WRIO:	[BR]_AC, J/IOWR

	.DCODE
714:	IOT,		B/10,	J/BIXUB
715:	IOT,		B/14,	J/BIXUB
724:	IOT,		B/0,	J/BIXUB
725:	IOT,		B/4,	J/BIXUB
	.UCODE

1644:
BIXUB:	[BRX]_[AR],		;SAVE EFFECTIVE ADDRESS
	CALL [IORD]		;GO GET THE DATA
1647:	[BR]_[AR],		;COPY DATA ITEM
	B DISP			;SEE IF SET OR CLEAR
=1011	[BR]_[BR].OR.AC,	;SET BITS
	J/BIXUB1		;GO DO WRITE
	[BR]_[BR].AND.NOT.AC,	;CLEAR BITS
	J/BIXUB1		;GO DO WRITE

BIXUB1:	[AR]_[BRX],		;RESTORE ADDRESS
	J/IOWR
;SUBROUTINE TO READ FROM AN IO DEVICE
;CALL WITH:
;	SECTION 0 EFFECTIVE ADDRESS IN AR
;	INSTRUCTION IN HR
;RETURN 3 WITH WORD OR BYTE IN AR
;
=0
IORD:	CLR IO BUSY,		;CLEAR BUSY
	CALL [IOEA]		;COMPUTE IO EA
	B DISP
=10111	[BR]_VMA IO READ,	;BYTE MODE
	IO BYTE/1,		;SET BYTE FLAG
	J/IORD1			;GO DO C/A CYCLE
=11111	[BR]_VMA IO READ	;WORD MODE
=
=0
IORD1:	VMA_[AR].OR.[BR] WITH FLAGS,
	CALL [IOWAIT]		;WAIT FOR THINGS COMPLETE
	MEM READ,		;MAKE SURE REALLY READY
	[BR]_IO DATA,		;PUT DATA IN BR
	B DISP			;SEE IF BYTE MODE
=0111	TR [AR], #/1, J/IORD2	;BYTE MODE SEE IF ODD
	[AR]_[BR], RETURN [3]	;ALL DONE

;HERE ON WORD MODE
=0
IORD2:	[BR]_[BR]*.5, SC_5,	;LEFT BYTE
	J/IORD3			;GO SHIFT IT
	[AR]_[BR].AND.#,	;MASK IT
	#/377, RETURN [3]	;ALL DONE

=0
IORD3:	[BR]_[BR]*.5,		;SHIFT OVER 
	STEP SC, J/IORD3	; ..
	[AR]_[BR].AND.#,	;MASK IT
	#/377, RETURN [3]	;ALL DONE
;ROUTINE TO WRITE TO AN IO DEVICE
;CALL WITH:
;	SECTION 0 EFFECTIVE ADDRESS IN AR
;	INSTRUCTION IN HR
;	WORD OR BYTE IN BR
;RETURNS BACK TO USER
;
=0
IOWR:	CLR IO BUSY,		;CLEAR BUSY
	CALL [IOEA]		;COMPUTE IO EA
	B DISP
=10111	TR [AR], #/1, J/IOWR2	;BYTE MODE
=11111	[ARX]_VMA IO WRITE	;SETUP FLAGS
=
IOWR1:	VMA_[AR].OR.[ARX] WITH FLAGS
=0	MEM WRITE, MEM_[BR],	;SEND DATA
	CALL [IOWAIT]		;WAIT FOR DATA
	DONE			;RETURN

;HERE FOR BYTE MODE
=0
IOWR2:	[BR]_[BR]*2, SC_5,	;ODD--MOVE LEFT
	J/IOWR3			; ..
	[ARX]_VMA IO WRITE,	;SETUP FLAGS
	IO BYTE/1, J/IOWR1	; ..

=0
IOWR3:	[BR]_[BR]*2, STEP SC,	;SHIFT LEFT
	J/IOWR3			;KEEP SHIFTING
	[ARX]_VMA IO WRITE,	;SETUP FLAGS
	IO BYTE/1, J/IOWR1	; ..
;HERE TO COMPUTE IO EFFECTIVE ADDRESS
;CALL WITH:
;	SECTION 0 EFFECTIVE ADDRESS IN AR
;	INSTRUCTION IN HR
;RETURN 1 WITH EA IN AR
;
=0
IOEA:	VMA_[PC]-1,		;GET INSTRUCTION
	START READ,		; ..
	CALL [LOADAR]		;PUT WORD IN AR
	[BRX]_.NOT.[AR]		;SEE IF IN RANGE 700-777
	TL [BRX], #/700000	; ..
=0
IOEA1:	TL [HR], #/20, J/IOEA2	;INDIRECT?
	WORK[YSAVE]_[AR] CLR LH, ;DIRECT IO INSTRUCTION
	J/IOEA1			;SAVE Y FOR EA CALCULATION
=0
IOEA2:	[AR]_WORK[YSAVE],	;@--GET SAVED Y
	J/IOEAI			;GET Y AND GO
	EA MODE DISP		;WAS THERE INDEXING?
=1101	[ARX]_XR, SKIP ADL.LE.0, ;SEE IF LOCAL OR GLOBAL INDEXING
	2T, J/IOEAX		; ..
	[AR]_WORK[YSAVE],	;JUST PLAIN IO
	CLR IO LATCH, RETURN [1]

IOEAI:	READ [HR], DBUS/DP,	;LOAD XR FLOPS IN CASE
	LOAD INST EA		; THERE IS INDEXING
	TL [HR], #/17		;WAS THERE ALSO INDEXING
=0	[AR]_[AR]+XR, 3T, HOLD LEFT ;YES--ADD IN INDEX VALUE
	VMA_[AR], START READ	;FETCH DATA WORD
	MEM READ, [AR]_MEM,	;GO GET DATA WORD
	CLR IO LATCH, RETURN [1]

=0
IOEAX:	[AR]_[ARX]+WORK[YSAVE],	;GLOBAL INDEXING
	CLR IO LATCH, RETURN [1]
	[AR]_[ARX]+WORK[YSAVE]	;LOCAL INDEXING
	[AR]_0, HOLD RIGHT,
	CLR IO LATCH, RETURN [1]
;WAIT FOR IO TO COMPLETE
;RETURNS 1 OR PAGE FAILS
;
IOWAIT:	SC_S#, S#/200,		;DELAY
	[T0]_VMA,		;GET VMA
	SKIP/-IO BUSY		;SEE IF BUSY YET
=00
IOW1:	CLR IO LATCH,		;WENT BUSY
	WORK[SV.VMA]_[T0],	;MAKE SURE SV.VMA IS SETUP
	J/IOW2			;WAIT FOR IT TO CLEAR
	SC_SC-1, SCAD DISP, 5T,	;SEE IF DONE YET
	SKIP/-IO BUSY,		; ..
	J/IOW1			;BACK TO LOOP
	CLR IO LATCH,		;WENT BUSY AND TIMEOUT
	WORK[SV.VMA]_[T0],	;MAKE SURE SV.VMA IS SETUP
	J/IOW2			; ..
	WORK[SV.VMA]_[T0],	;MAKE SURE SV.VMA IS SETUP
	J/IOW5			;GO TRAP

IOW2:	SC_S#, S#/777,		;GO TIME IO
	SKIP/-IO BUSY		; ..
=0
IOW3:	CLR IO LATCH,		;TRY TO CLEAR LATCH
	STEP SC, J/IOW4		;STILL BUSY
	RETURN [1]		;IDLE

=0
IOW4:	CLR IO LATCH, 5T,	;TRY TO CLEAR LATCH
	SKIP/-IO BUSY,		;SEE IF STILL BUSY
	J/IOW3			; ..
IOW5:	[BRX]_[200000] XWD 0, J/HARD
.TOC	"SMALL SUBROUTINES"

;HERE ARE A COLLECTION ON 1-LINE SUBROUTINES
LOADAR:	MEM READ, [AR]_MEM,	;FROM MEMORY TO AR
	RETURN [1]		;RETURN TO CALLER

LOADARX: MEM READ, [ARX]_MEM, RETURN [1]

LOADQ:	MEM READ, Q_MEM, RETURN [1]

CLARXL:	[ARX]_0, HOLD RIGHT, RETURN [1]

INCAR:	[AR]_[AR]+1, RETURN [1]

SBRL:	[BR]_[BR]*2, RETURN [1]

STRTIO:	VMA_[AR] WITH FLAGS, RETURN [1]

STOBR:	MEM WRITE, MEM_[BR], RETURN [4]

STOPC:	MEM WRITE, MEM_[PC], RETURN [1]

AC_ARX:	AC_[ARX], RETURN [1]
.TOC	"UNDEFINED IO INSTRUCTIONS"

	.DCODE
703:	I,	B/3,	J/IOT700
706:	I,	B/6,	J/IOT700
	I,	B/7,	J/IOT700

716:	I,	B/6,	J/IOT710
	I,	B/7,	J/IOT710

726:	I,	B/6,	J/IOT720
	I,	B/7,	J/IOT720

730:	I,	B/0,	J/IOT730
	I,	B/1,	J/IOT730
	I,	B/2,	J/IOT730
	I,	B/3,	J/IOT730
	I,	B/4,	J/IOT730
	I,	B/5,	J/IOT730
	I,	B/6,	J/IOT730
	I,	B/7,	J/IOT730

740:	I,	B/0,	J/IOT740
	I,	B/1,	J/IOT740
	I,	B/2,	J/IOT740
	I,	B/3,	J/IOT740
	I,	B/4,	J/IOT740
	I,	B/5,	J/IOT740
	I,	B/6,	J/IOT740
	I,	B/7,	J/IOT740

750:	I,	B/0,	J/IOT750
	I,	B/1,	J/IOT750
	I,	B/2,	J/IOT750
	I,	B/3,	J/IOT750
	I,	B/4,	J/IOT750
	I,	B/5,	J/IOT750
	I,	B/6,	J/IOT750
	I,	B/7,	J/IOT750

760:	I,	B/0,	J/IOT760
	I,	B/1,	J/IOT760
	I,	B/2,	J/IOT760
	I,	B/3,	J/IOT760
	I,	B/4,	J/IOT760
	I,	B/5,	J/IOT760
	I,	B/6,	J/IOT760
	I,	B/7,	J/IOT760
770:	I,	B/0,	J/IOT770
	I,	B/1,	J/IOT770
	I,	B/2,	J/IOT770
	I,	B/3,	J/IOT770
	I,	B/4,	J/IOT770
	I,	B/5,	J/IOT770
	I,	B/6,	J/IOT770
	I,	B/7,	J/IOT770
	.UCODE

1650:
IOT700:	UUO
1651:
IOT710:
.IFNOT/UBABLT
	UUO
.IF/UBABLT
	J/BLTX		;GO TO COMMON CODE FOR UBABLT INSTRS
.ENDIF/UBABLT
1652:
IOT720:	UUO
1653:
IOT730:	UUO
1654:
IOT740:	UUO
1655:
IOT750:	UUO
1656:
IOT760:	UUO
1657:
IOT770:	UUO
.TOC	"UMOVE AND UMOVEM"

	.DCODE
704:	IOT,	J/UMOVE
	IOT,	J/UMOVEM
	.UCODE

1754:
UMOVE:	VMA_[AR],		;LOAD VMA
	START READ,		;START MEMORY
	SPEC/PREV		;FORCE PREVIOUS
	MEM READ,		;WAIT FOR MEMORY
	[AR]_MEM,		;PUT DATA IN AR
	J/STAC			;GO PUT AR IN AC

1755:
UMOVEM:	VMA_[AR],		;LOAD VMA
	START WRITE,		;START MEMORY
	SPEC/PREV		;FORCE PREVIOUS
	[AR]_AC,		;FETCH AC
	J/STMEM			;STORE IN MEMORY
;HERE WITH HALT CODE IN THE T1
=010*
HALTED:	WORK[SV.ARX]_[ARX],	;SAVE TEMP REGISTER
	CALL [SAVVMA]		;PUT VMA IN WORK[SV.VMA]
=110*	ABORT MEM CYCLE,		;ABORT CYCLE IN PROGRESS
	CALL [WRTHSB]		;WRITE HALT STATUS BLOCK
=111*
PWRON:	[ARX]_0, VMA PHYSICAL WRITE ;STORE HALT CODE
=
	MEM WRITE, MEM_[T1]	; IN LOCATION 0
=0	NEXT [ARX] PHYSICAL WRITE,
	CALL [STOPC]
H1:	SET HALT, J/HALTLP	;TELL CONSOLE WE HAVE HALTED


4:	UNHALT,			;RESET CONSOLE
	SKIP EXECUTE, J/CONT	;SEE IF CO OR EX
5:
HALTLP:	SKIP/-CONTINUE, J/4	;WAIT FOR CONTINUE

=0
CONT:	VMA_[PC],		;LOAD PC INTO VMA
	FETCH,			;START READ
	J/XCTGO			;DO THE INSTRUCTION
	[AR]_VMA IO READ	;PUT FLAGS IN AR
=0	[AR]_[AR].OR.#,		;PUT IN ADDRESS
	#/200000, HOLD LEFT,	; OF CSL REGISTER
	CALL [STRTIO]
CONT1:	MEM READ,		;WAIT FOR DATA
	[HR]_MEM,		;PUT IN HR
	LOAD INST,		;LOAD IR, ETC.
	J/XCT1			;GO DO THE INSTRUCTION
.TOC	"WRITE HALT STATUS BLOCK"

;THE HALT STATUS BLOCK LOOKS LIKE:

;	!=======================================================!
;	!00!                        MAG                         !
;	!-------------------------------------------------------!
;	!01!                         PC                         !
;	!-------------------------------------------------------!
;	!02!                         HR                         !
;	!-------------------------------------------------------!
;	!03!                         AR                         !
;	!-------------------------------------------------------!
;	!04!                        ARX                         !
;	!-------------------------------------------------------!
;	!05!                         BR                         !
;	!-------------------------------------------------------!
;	!06!                        BRX                         !
;	!-------------------------------------------------------!
;	!07!                        ONE                         !
;	!-------------------------------------------------------!
;	!10!                        EBR                         !
;	!-------------------------------------------------------!
;	!11!                        UBR                         !
;	!-------------------------------------------------------!
;	!12!                        MASK                        !
;	!-------------------------------------------------------!
;	!13!                        FLG                         !
;	!-------------------------------------------------------!
;	!14!                         PI                         !
;	!-------------------------------------------------------!
;	!15!                        XWD1                        !
;	!-------------------------------------------------------!
;	!16!                         T0                         !
;	!-------------------------------------------------------!
;	!17!                         T1                         !
;	!=======================================================!
;	!         VMA FLAGS         !            VMA            !
;	!=======================================================!
;START AT 1 TO DUMP 2901 REGISTERS INTO MAIN MEMORY
1:	WORK[SV.ARX]_[ARX],	;SAVE TEMP REGISTER
	CALL [SAVVMA]		;WORK[SV.VMA]_VMA
11:	[ARX]_WORK[HSBADR]
=10*	ABORT MEM CYCLE, CALL [DUMP]
	SET HALT, J/H1


WRTHSB:	[ARX]_WORK[HSBADR], ;GET ADDRESS OF HSB
	SKIP AD.LE.0, 4T	;SEE IF VALID
=0	READ [MASK], LOAD PI,	;TURN OFF PI SYSTEM
	J/DUMP			; AND GO TAKE DUMP
	[ARX]_WORK[SV.ARX],
	RETURN [2]		;DO NOT DUMP ANYTHING

SAVVMA:	[ARX]_VMA
	WORK[SV.VMA]_[ARX],
	RETURN [10]
;DUMP OUT THE 2901
DUMP:	READ [ARX], VMA PHYSICAL WRITE
=0*	MEM WRITE, MEM_[MAG], CALL [NEXT]
	MEM WRITE, MEM_[PC]
	NEXT [ARX] PHYSICAL WRITE
=0*	MEM WRITE, MEM_[HR], CALL [NEXT]
	MEM WRITE, MEM_[AR]
=0*	WORK[SV.AR]_[AR], CALL [NEXT]
	[AR]_WORK[SV.ARX]
=0*	MEM WRITE, MEM_[AR], CALL [NEXT]
	MEM WRITE, MEM_[BR]
	NEXT [ARX] PHYSICAL WRITE
=0*	MEM WRITE, MEM_[BRX], CALL [NEXT]
	MEM WRITE, MEM_[ONE]
	NEXT [ARX] PHYSICAL WRITE
=0*	MEM WRITE, MEM_[EBR], CALL [NEXT]
	MEM WRITE, MEM_[UBR]
	NEXT [ARX] PHYSICAL WRITE
=0*	MEM WRITE, MEM_[MASK], CALL [NEXT]
	MEM WRITE, MEM_[FLG]
	NEXT [ARX] PHYSICAL WRITE
=0*	MEM WRITE, MEM_[PI], CALL [NEXT]
	MEM WRITE, MEM_[XWD1]
	NEXT [ARX] PHYSICAL WRITE
=0*	MEM WRITE, MEM_[T0], CALL [NEXT]
	MEM WRITE, MEM_[T1]
=0*	[AR]_WORK[SV.VMA], CALL [NEXT]
	MEM WRITE, MEM_[AR]
HSBDON:	[AR]_WORK[SV.AR]
	[ARX]_WORK[SV.VMA]
	VMA_[ARX]
	[ARX]_WORK[SV.ARX],
	RETURN [6]