1
0
mirror of https://github.com/PDP-10/its.git synced 2026-01-27 12:42:10 +00:00
Files
PDP-10.its/src/kshack/itspag.98
Lars Brinkhoff 52ef5130b7 KS10 microcode.
Plus assorted KS10-related documents.
2018-06-12 07:58:19 +02:00

425 lines
12 KiB
Plaintext
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
; -*- Fundamental -*-
.TOC "ITS PAGE REFILL CODE"
.IF/ITS
CLEANUP DONE "END STATE, SKIP IRPT, J/PFTRAP"
CLEANUP AND TRAP "[AR]_WORK[SV.VMA], SKIP/TRAP CYCLE, J/CLTRP"
;ITS page table entry:
; (when shifted left once the valid bit, cache bit, write bit and page
; number will be in the right place for loading the hardware.)
PTE VALID/=<91> ;2.8 (internal to the microcode)
PTE AGE/=<94> ;2.5
ALL=1 ; (actually a field of length 1)
PTE WRITE/=<94> ;2.5 (internal to the microcode)
PTE CACHE/=<95> ;2.4
PTE PAGE/=<98:107> ;2.1 - 1.1
;Hardware page table control bits:
PT VALID/=<90> ;2.9
PT WRITE/=<93> ;2.6
PT CACHE/=<94> ;2.5
PT PAGE/=<97:107> ;2.2 - 1.1
EVEN=3776
ALL=3777
; VMA flags: Page fail word flags:
;4.9 User mode User mode
;FORCE USER
;4.8 Exec mode Nonexistent IO register
NONEXISTENT IO REGISTER/=<91> ;J/IOW5
;4.7 Instruction fetch Nonexistent memory
NONEXISTENT MEMORY/=<92> ;J/PFD
;4.6 Read Uncorrectable memory error
UNCORRECTABLE MEMORY ERROR/=<93> ;J/PFD, J/BADDATA
;4.5 Write test
;WRITE TEST
;4.4 Write Memory write
;WRITE CYCLE
;4.3 2.9 from page table entry
;4.2 Don't cache 2.8 from page table entry
PAGE ACCESS/=<96:97>
;4.1 Physical Physical
;PHYSICAL
;3.4 - 1.1 Address Address
ADDRESS HIGH/=<104:107>
MEMORY=3 ;20 bits of physical memory address.
IO=17 ;22 bits of IO address.
ALL=17
; (These VMA flags only from DP:)
;3.8 IO cycle IO cycle
;IO CYCLE
;3.7 WRU cycle
;3.6 Vector cycle
;3.5 Byte cycle IO byte cycle
;IO BYTE
; (These VMA flags only from #:)
;3.9 - 3.7 XCTR control
;3.6 Hack for AREAD: DROM supplies 4.6 - 4.4 and 3.4
;3.5 Ignore 4.9 - 3.7 from # and use 4.9 - 3.5 from DP instead.
;3.4 Load the VMA
;3.3 Extended address: Use 3.4 - 3.1
;3.2 Wait: Start a cycle.
;3.1 Hack for BWRITE: DROM supplies 3.2
.DCODE
257: IOT, AC, J/UUO257 ;Used to be MAP
.UCODE
1553:
UUO257: UUO
;The hardware comes here with a page fail or pending interrupt:
3777:
PAGE-FAIL:
WORK[SV.AR]_[AR]
;;INTERRUPT-TRAP macro (which nobody uses) does the above and comes
;;here:
ITRAP: WORK[SV.ARX]_[ARX] ;J/MVSKP
WORK[SV.BRX]_[BRX]
[BRX]_VMA ;BRX: FLAGS,,VMA
WORK[SV.VMA]_[BRX],
SKIP IRPT ;See if interrupt (saves a dispatch)
=0000
PFD: DBM/PF DISP, DBUS/DBM, ;Puts page fail condition on
AD/D, DEST/PASS, 4T, ;DP 18-21.
DISP/DP LEFT, J/PFD ;Dispatch on it.
=0001 WORK[SV.BR]_[BR], ;(1) Interrupt
J/PF-INT
=0011 [BRX]_IO DATA, ;(3) Parity
AD PARITY OK/0, ;Don't look at parity.
J/BADDATA
=0101 [BRX]_[100000] XWD 0, ;(5) NXM
J/HARD
=0111 [BRX]_[140000] XWD 0, ;(7) NXM & Parity
J/HARD
=1000 WORK[SV.BR]_[BR], ;(10) Read-only page
J/PFMAP
=1001 WORK[SV.BR]_[BR], ;[123] (11) 1 ms timer and movsrj
J/PF-INT
=1010 WORK[SV.BR]_[BR], ;(12) Nonexistent page
J/PFMAP
=1011 WORK[SV.BR]_[BR], ;(13) Exec/User mismatch
J/PFMAP
=
;Here is how a hard memory error is handled:
BADDATA:
WORK[BADW0]_[BRX] ;Save bad word.
[BRX]_[040000] XWD 0
;;I/O failures come here from J/IOW5 with 200000 in BRX:
HARD: WORK[SV.BR]_[BR] ;Finally save BR
=0 [BR]_VMA, ;VMA for page fail word.
CALL [ABORT] ;Clear page fault condition.
[BR]_[BR].AND.#, ;Save interesting flags:
FORCE USER/1, PHYSICAL/1,
IO CYCLE/1, IO BYTE/1,
ADDRESS HIGH/ALL, HOLD RIGHT
= [BRX]_[BRX].OR.[BR] ;BRX: Page fail word
PAGE FAIL TRAP
;Here is what happens when the initial dispatch on the page fail condition
;tells us an interrupt is pending:
PF-INT: SKIP IRPT ;Timer trap?
=00 [AR]_WORK[TIME1], ;Yes: Get low word.
SPEC/CLRCLK, ; Clear clock flag.
CALL [TOCK] ; Do the update. TOCK returns 2.
CLEANUP AND TRAP ;No: External interrupt. Jump away
ABORT MEM CYCLE ;Clear 1ms flags.
=
.IF/PCST ;Take a PC sample every millisecond
[AR]_WORK[SV.VMA] ;Recover VMA and flags
[ARX]_WORK[PCST], SKIP DP0 ;Skip if PC sampling is enabled
=0 [ARX]_WORK[SV.ARX], J/PAGE-CONTINUE1 ;Disabled or table full
[BR]_PC WITH FLAGS
TL [AR], FETCH/1 ;Skip if PC points at current instruction
=0 [BR]_[BR]-1, HOLD LEFT ;No, back up the PC that gets stored
WORK[PCST]_[ARX]+[XWD1] ;Increment the AOBJN pointer
[ARX] LEFT_0 ;Clear high bits of physical address damn it
VMA_[ARX], VMA PHYSICAL WRITE ;Store PC into sample table
MEM WRITE, MEM_[BR], J/PAGE-CONTINUE
.IFNOT/PCST
[AR]_WORK[SV.VMA], ;Restore VMA and continue where
J/PAGE-CONTINUE ; we left off.
.ENDIF/PCST
;Here we handle a soft page failure. BRX contains VMA FLAGS,,VMA.
PFMAP: ABORT MEM CYCLE ;Clear page fail condition.
TL [BRX], WRITE TEST/1 ;Write test?
=0 [BRX]_[BRX].OR.#, ;Yes: Turn into simple write.
WRITE CYCLE/1, HOLD RIGHT
[BRX]_[BRX].AND.#, ;Save interesting flags:
FORCE USER/1, WRITE CYCLE/1, PHYSICAL/1,
ADDRESS HIGH/MEMORY, HOLD RIGHT
= [AR]_[BRX], ;Copy virtual address and
SC_9. ;prepare to shift 11 places.
=0
PFMAP1: [AR]_[AR]*.5, ;Right adjust page #
STEP SC, J/PFMAP1
[AR]_[AR].AND.# CLR LH, ;AR: index off DBR
#/77
= READ [BRX], SKIP DP0 ;User ref?
=0 READ [BRX], SKIP DP18, ;Exec high ref?
J/EXEC-DBR
READ [BRX], SKIP DP18, ;User high ref?
J/USER-DBR
=
=0
USER-DBR:
[AR]_[AR]+WORK[DBR1], ;User low
J/GOTDBR
[AR]_[AR]+WORK[DBR2], ;User high
J/GOTDBR
=
=0
EXEC-DBR:
[AR]_[AR]+WORK[DBR4], ;Exec low
J/GOTDBR
[AR]_[AR]+WORK[DBR3], ;Exec high
J/GOTDBR
=
;BRX: Original VMA FLAGS,,VMA modified as for a page fail word.
;AR: Address of page table word.
GOTDBR: VMA_[AR], START READ, VMA PHYSICAL
MEM READ, [BR]_MEM
TR [BRX], #/2000 ;Odd?
=0 [ARX]_[BR], ;Yes: entry is in right half, just copy it
J/PTWRH ; into ARX.
[ARX]_[BR] SWAP, ;No: entry is in left half, so copy in ARX
J/PTWLH ; is swapped first.
=
PTWRH: [BR]_[BR].AND.NOT.#, ;BR gets the word to write back with the
PTE AGE/ALL, ; age bits cleared in the right half.
HOLD LEFT,
SKIP DP18, J/PTWTST ;Test 2.9 of entry.
PTWLH: [BR]_[BR].AND.NOT.#, ;BR gets the word to write back with the
PTE AGE/ALL, ; age bits cleared in the left half.
HOLD RIGHT,
SKIP DP0, J/PTWTST ;Test 2.9 of entry.
=0
PTWTST: TR [ARX], #/200000, J/PTWTS0 ;0X: Test 2.8
TR [ARX], #/200000, J/PTWTS1 ;1X: Test 2.8
=
=0
PTWTS0: [BRX]_[BRX].OR.#, ;01: Read only
PAGE ACCESS/1, ;Indicate that in page fail word.
HOLD RIGHT,
J/READ-ONLY
PAGE FAIL TRAP ;00: Not accessible.
=
=0
PTWTS1: [ARX]_[ARX].OR.#, ;11: Read/Write
PTE WRITE/1, ;Set Writable bit in page table.
HOLD LEFT,
J/PAGE-REFILL
[BRX]_[BRX].OR.#, ;10: Read/Write/First
PAGE ACCESS/2, ;Indicate that in page fail word.
HOLD RIGHT,
J/READ-ONLY
=
READ-ONLY:
TL [BRX], ;Were we perhaps trying to write?
WRITE CYCLE/1
=0 PAGE FAIL TRAP ;That would be a problem wouldn't it!
[ARX]_[ARX].AND.NOT.#, ;Clear writable bit in page table.
PTE WRITE/1,
HOLD LEFT,
J/PAGE-REFILL
=
;BRX: Original VMA FLAGS,,VMA modified as for a page fail word.
;AR: Address of page table word.
;ARX: Half formed page table entry in right half.
;BR: Original page table word with the age bit set.
PAGE-REFILL:
VMA_[AR], ;Prepare to put the word back.
START WRITE,
VMA PHYSICAL
MEM WRITE, ;Write it back.
MEM_[BR]
[AR]_WORK[SV.VMA] ;AR: For PAGE-CONTINUE to use.
[BR]_[AR].AND.NOT.#, ;Clear bits which start a cycle.
READ CYCLE/1, WRITE CYCLE/1,
WRITE TEST/1, HOLD RIGHT
[BR]_[AR].AND.NOT.#, ;Make DEC page number even.
#/1000, HOLD LEFT
VMA_[BR], 3T, DP FUNC/1 ;Restore VMA and set User according to
;what it was.
[ARX]_([ARX].OR.#)*2, ;Set Valid bit and shift into position.
3T, PTE VALID/1,
LOAD PAGE TABLE ;Load page table on next instruction.
[ARX]_[ARX].AND.# CLR LH, ;Mask out all but the correct
PT VALID/1, PT WRITE/1, ; bits. Make the DEC physical
PT CACHE/1, PT PAGE/EVEN ; page number even.
[BR]_[BR].OR.#, ;Make DEC page number in VMA odd.
#/1000, HOLD LEFT
VMA_[BR], 3T, DP FUNC/1 ;Restore VMA again for the odd page.
[ARX]_[ARX].OR.#, ;Then the odd physical page.
#/1, HOLD LEFT,
LOAD PAGE TABLE ;Load page table on next instruction.
READ [ARX],
J/PAGE-CONTINUE
;Return to interrupted microinstruction after a successful page table
;reload or a timer trap. AR should contain the right VMA to restart the
;memory cycle.
PAGE-CONTINUE:
[ARX]_WORK[SV.ARX] ;Restore saved stuff
PAGE-CONTINUE1:
[BR]_WORK[SV.BR]
[BRX]_WORK[SV.BRX]
VMA_[AR], ;MAKE MEM REQUEST
DP FUNC/1, 3T, ;FROM DATA PATH
WAIT/1 ;WAIT FOR PREVIOUS CYCLE TO
; COMPLETE. (NEED THIS TO
; START ANOTHER CYCLE)
[AR]_WORK[SV.AR],
RETURN [0]
;;; Here we have hair to back us out of an instruction in case we have to
;;; deliver a page fault or an interrupt. Think of it as micro PCLSRing.
;;; Anybody who comes to this page to deliver a page fault better have set
;;; up BRX to contain the right page fail word first. Cleanup handlers
;;; better not smash it either.
;PAGE FAIL TRAP macro does:
; TL [FLG], FLG.PI/1, ;PI cycle?
; J/PFT
=0
PFT: HALT [IOPF] ;Yes: IO Page Failure
CLEANUP AND TRAP ;No: deliver hard page fault.
=
;CLEANUP AND TRAP macro does:
; [AR]_WORK[SV.VMA],
; SKIP/TRAP CYCLE, ;See if trap cycle.
; J/CLTRP
=0
CLTRP: TL [AR], FETCH/1, ;Is this an instruction fetch?
J/CLTRP1
[AR]_WORK[TRAPPC] ;This is a trap cycle.
= READ [AR], LOAD FLAGS, ;Restore PC flags.
J/CLDISP
=0
.IF/1PROC ;Fault/interrupt while in instruction fetch
CLTRP1: TL [FLG], FLG.2PROC/1, J/CLTRP2
.IFNOT/1PROC
CLTRP1: CLEANUP DONE ;Instruction fetch: Everything is clean.
.ENDIF/1PROC
;;Many things jump here to backup the PC and cleanup.
FIXPC: [PC]_[PC]-1, HOLD LEFT
= ;;Many things jump here to cleanup.
CLDISP: READ [FLG], DBUS/DP, DISP/DP, 3T, J/CLEANUP
;;CLEANUP DISP macro (which nobody uses) does the above.
.IF/1PROC
=0
CLTRP2: TAKE 1-PROCEED TRAP ;Take one-proceed trap instead of this one
CLEANUP DONE
.ENDIF/1PROC
=0000
CLEANUP: ;;Dispatch table to cleanup after a page fault or interrupt.
CLEANED: ;;J/BLT-CLEANUP ;(0) Normal case: No more cleanup needed.
CLEANUP DONE ;Go deliver page fault or interrupt.
=0001 [AR]_WORK[SV.ARX], ;(1) BLT
J/BLT-CLEANUP
;(2) Unused.
=0011 STATE_[EDIT-SRC], ;(3) SRC IN STRING MOVE
J/STRPF
=0100 STATE_[EDIT-DST], ;(4) DST IN STRING MOVE
J/STRPF
=0101 STATE_[SRC], ;(5) SRC+DST IN STRING MOVE
J/BACKD
=0110 STATE_[EDIT-DST], ;(6) FILL IN MOVSRJ
J/STRPF4
=0111 STATE_[EDIT-SRC], ;(7) DEC TO BIN
J/PFDBIN
=1000 STATE_[EDIT-SRC], ;(10) SRC+DST IN COMP
J/CMSDST
=1001 END STATE, J/BACKS ;(11) EDIT SRC FAIL
=1010 END STATE, J/BACKD ;(12) EDIT DST FAIL
=1011 STATE_[EDIT-SRC], ;(13) SRC+DST IN EDIT
J/BACKD
=
;CLEANUP DONE macro does:
; END STATE, SKIP IRPT, J/PFTRAP
=0
PFTRAP: TR [PI], ;Here to deliver page fault after cleanup.
PI.IP1/1, PI.IP2/1, ; This hack figures out what 3 locations to
PI.IP3/1, PI.IP4/1, ; use to deliver the page fault.
J/PFTDSP
TAKE INTERRUPT ;Here to deliver interrupt after cleanup.
; J/PI after setting FLG.PI
=
=0
PFTDSP: TR [PI], PI.IP1/1, PI.IP2/1, J/PFTDS1
TR [PI], PI.IP5/1, PI.IP6/1, J/PFTDS0
=0
PFTDS1: TR [PI], PI.IP1/1, J/PFTD11
TR [PI], PI.IP3/1, J/PFTD10
=0
PFTDS0: TR [PI], PI.IP5/1, J/PFTD01
TR [PI], PI.IP7/1, J/PFTD00
=0
PFTD11: [AR]_0 XWD [443], J/PFTRAP1
[AR]_0 XWD [446], J/PFTRAP1
=0
PFTD10: [AR]_0 XWD [451], J/PFTRAP1
[AR]_0 XWD [454], J/PFTRAP1
=0
PFTD01: [AR]_0 XWD [457], J/PFTRAP1
[AR]_0 XWD [462], J/PFTRAP1
=0
PFTD00: [AR]_0 XWD [465], J/PFTRAP1
[AR]_0 XWD [440], J/PFTRAP1
=
PFTRAP1:
[AR]_[AR]+[EBR], ; Where to store PFW
VMA PHYSICAL WRITE
MEM WRITE, ; Store PFW
MEM_[BRX]
.IF/1PROC
=0** NEXT [AR] PHYSICAL WRITE, ; Where to store old PC
CALL [STORE-INT-PC]
.IFNOT/1PROC
NEXT [AR] PHYSICAL WRITE ; Where to store old PC
[BR]_PC WITH FLAGS ; Get old PC
MEM WRITE, ; Store old PC
MEM_[BR]
.ENDIF/1PROC
[AR]_[AR]+1, ; Where to get new PC
VMA PHYSICAL READ,
J/GOEXEC
.IF/1PROC
STORE-INT-PC:
[BR]_PC WITH FLAGS ; Get old PC
TL [FLG], FLG.1PROC/1 ; Was the instruction being one-proceeded?
=0 [BR]_[BR].OR.#, OIPBIT/1, ;It was, turn pc flag back on
HOLD RIGHT, J/STORE-INT-PC-2
STORE-INT-PC-1:
MEM WRITE, MEM_[BR], RETURN [4]
STORE-INT-PC-2:
[FLG]_[FLG].AND.NOT.#, FLG.1PROC/1, ;Clear 1-proceed flags
FLG.2PROC/1, HOLD RIGHT, J/STORE-INT-PC-1
.ENDIF/1PROC
.ENDIF/ITS