I'm trying to understand the MTPI (and its MFPI counterpart) instruction on the PDP/11.
As far as I understood, it:
it retrieves a value from the "current" memory space with the current mapping (e.g. kernel mapping). Like: (R0): retrieve from the current memory space-address which is in the R0 register.
it then determines the physical memory location of the "previous"-stackpointer in the "previous" memory space (e.g. the user mapping) and then stores it then on that stack
I wrote the following to verify this. If all goes well, it should end with the 'Z' (zero) flag set. In simh/pdp11 this is not what happens, the Z-flag is not set. So clearly my understanding of it is wrong. Any hints?
; initialize kernel- and user stackpointers
; kernel
MOV #1000,R6
; user
MOV #0177717,R0
MOV #1000,(R0)
; make sure current run-mode is kernel and previous is user
MOV #0177776,R0
MOV #030000,(R0)
NOP
; user: 020000-040000 will be mapped to physical address 060000
MOV #0177642,R0
; 060000 / 0100 (0100 => 64 decimal)
MOV #0600,(R0)
NOP
; user: make sure write- and read-access is possible
MOV #0177602,R0
MOV #077406,(R0)
; kernel: flat mapping
MOV #0172340,R0
MOV #0000,(R0)
NOP
; kernel: make sure write- and read-access is possible
MOV #0172300,R0
MOV #077406,(R0)
; enable MMU
MOV #0177572,R0
BIS #1,(R0)
; write word on stack that will be checked for to be at the
; remapped address
MOV #01234,-(SP)
; this address in kernel space should be 060000 in userspace
MOV #020000,R0
MTPI (R0)
NOP
; check for 01234 at 060000 in kernel space
MOV #060000,R0
CMP #01234,(R0)
NOP
HALT