1
0
mirror of https://github.com/wfjm/w11.git synced 2026-02-05 08:15:19 +00:00

re-organize w11a_known_differences [skip ci]

This commit is contained in:
wfjm
2022-08-26 08:22:46 +02:00
parent 7f9506b201
commit cb152cdd33
7 changed files with 138 additions and 78 deletions

View File

@@ -0,0 +1,31 @@
## Differences in unspecified behavior between w11a and KB11-C (11/70)
### State of N and Z and registers after a `DIV` abort with `V=1`
The state of the N and Z condition codes is specified as unspecified for
the `DIV` instruction when V=1 is set after a zero divide or an overflow
condition.
See [1979 processor handbook](http://www.bitsavers.org/pdf/dec/pdp11/handbooks/PDP11_Handbook1979.pdf) on page 75.
After a `DIV` overflow, the w11 returns Z=0 and N based on the sign of the
full 32-bit result, as can be easily determined by xor'ing of the sign
bits of dividend and divisor.
This is also the most natural result, an overflow is certainly
not zero, and the sign is unambiguously determined by the inputs.
The SimH simulator also behaves like this. A real J11 and a real 11/70
can have N=0 even when dividend and divisor have opposite signs. And a
real 11/70 can have Z=1. Bottom line is, that the w11 differs from the
behavior of both the real 11/70 and the real J11 behavior.
The state of the result registers is also unspecified after a DIV with V=1.
SimH and a real J11 never modify a register when V=1 is set. A real 11/70
and the w11 do, but under different conditions, and leave different values
in the registers.
For gory details consult the [divtst](../tools/tests/divtst/README.md) code
and the log files for different systems in the
[data](../tools/tests/divtst/data/README.md) directory.
No software should depend on the unspecified behavior of the CPU, therefore
this is considered as the acceptable implementation difference.

View File

@@ -0,0 +1,24 @@
## Known differences between w11a and KB11-C (11/70)
### The 'instruction completed flag' in `MMR0` is not implemented
All PDP-11 processors with a fully functional MMU (11/45, 11/70, 11/44, and J11)
support the re-execution of an instruction after an MMU abort.
`MMR2` holds the virtual address of aborted instruction and `MMR1` holds
information about register changes. This can be used by a handler to roll back
the register changes and restart the instruction. This can be used to
implement demand paging or dynamic extension of stack segments.
The 11/70 and 11/45 are the only PDP-11 processors that also support the
recovery of an MMU abort of a stack push during trap or interrupt processing.
To distinguish between an instruction and a trap processing abort the
`MMR1` has a bit called `instruction completed`. It is will be set to 0
whenever an instruction is aborted and is 1 after a trap service flow is
aborted. The `MMR2` contains the vector address in the latter case.
Only the 11/70 and the 11/45 support this. No OS uses this.
And it's very difficult to construct a practical use case.
The w11a doesn't support the 'instruction completed' bit in `MMR1`. It is
always 0. And `MMR2` holds always the virtual address of the last instruction.

View File

@@ -0,0 +1,13 @@
## Known differences between w11a and KB11-C (11/70)
### A 'red stack violation' loses PSW, a 0 is pushed onto the stack
The 11/70, together with the 11/45, has the most elaborate stack protection
system of all PDP-11 models. A stack push via kernel stack is aborted when the
stack pointer is in the 'red zone' 16 words below the stack limit.
An emergency stack is set up, `SP` is set to 4, and PSW and PC are stored.
The w11a loses the PSW, a 0 is pushed.
'red stack aborts' are never recovered, all OS treat them as fatal errors.
This difference is therefore considered an acceptable implementation difference.

View File

@@ -0,0 +1,22 @@
## Known differences between w11a and KB11-C (11/70)
### Instruction fetch after `SPL`
The `SPL` instruction in the 11/70 always fetched the next instruction
regardless of current mode, pending device, or even console interrupts.
This is known as the infamous _SPL bug_, see
- https://minnie.tuhs.org/pipermail/tuhs/2006-September/002692.html
- https://minnie.tuhs.org/pipermail/tuhs/2006-October/002693.html
- https://minnie.tuhs.org/pipermail/tuhs/2006-October/002694.html
- https://minnie.tuhs.org/pipermail/tuhs/2006-October/002695.html
- https://minnie.tuhs.org/pipermail/tuhs/2006-October/002701.html
- https://minnie.tuhs.org/pipermail/tuhs/2006-October/002695.html
- https://minnie.tuhs.org/pipermail/tuhs/2006-October/002702.html
In the w11a, the `SPL` has 11/70 semantics in kernel mode, thus no
traps or interrupts, the instruction after the `SPL` is unconditionally
executed.
But in supervisor and user mode `SPL` really acts as `NOOP`, so traps and
interrupts are taken as for all other instructions.
**--> The w11a isn't bug compatible with the 11/70.**

View File

@@ -0,0 +1,24 @@
## Other differences between w11a and KB11-C (11/70)
### Usage of 11/70 `SYSID` register
In real 11/70's, the `SYSID` register contained an individual serial number.
The content of this register may be printed in some reports, but it certainly
has no effect on the logic of the code running on the system.
The w11 project uses the `SYSID` to encode the execution environment.
This allows distinguishing between operation on a real w11 and operation
in a software emulation under SimH or e11.
It can be used on test and verification codes to reconcile implementation
differences.
Usage of the w11 `SYSID` register
- the SYSID is divided into fields
- bit 15: emulator flag (0=w11,1=emulator)
- bit 14:12: type, encodes w11 or emulator type
- bit 11:09: cpu number on 11/74 systems
- bit 8:0: serial number
- current assignments are
- w11a: 010123
- SimH: 110234
- e11: 120345

View File

@@ -0,0 +1,11 @@
## Known differences between w11a and KB11-C (11/70)
### 18-bit UNIBUS address space not mapped into 22-bit address space
The 11/70 maps the 18 bit UNIBUS address space into the upper part of
the 22-bit extended mode address space. With UNIBUS mapping enabled, this
allows to access via 17000000:17757777 the memory exactly as a UNIBUS
device would see it.
The w11a doesn't implement this remapping, an access in the range
17000000:17757777 causes an NXM fault.

View File

@@ -1,75 +1,27 @@
# Summary of known differences and limitations for w11a CPU and systems
This file describes the differences and limitations of the w11 CPU and systems.
This file lists the differences and limitations of the w11 CPU and systems.
The issues of the w11 CPU and systems are listed in a separate document
[README_known_issues.md](README_known_issues.md).
### Table of content
### Known differences between w11a and KB11-C (11/70)
- [Instruction fetch after `SPL`](w11a_diff_70_spl_bug.md)
- ['red stack violation' loses PSW](w11a_diff_70_red_stack_abort.md)
- ['instruction completed flag' in `MMR0` is not implemented](w11a_diff_70_instruction_complete.md)
- [18-bit UNIBUS address space not mapped](w11a_diff_70_unibus_mapping.md)
- [Known differences between w11a and KB11-C (11/70)](#user-content-diff)
- [Differences in unspecified behavior cases between w11a and
KB11-C (11/70)](#user-content-unspec)
- [Known limitations](#user-content-lim)
- [Other differences](#user-content-other)
### <a id="diff">Known differences between w11a and KB11-C (11/70)</a>
- the `SPL` instruction in the 11/70 always fetched the next instruction
regardless of pending device or even console interrupts. This is known
as the infamous _spl bug_, see
- https://minnie.tuhs.org/pipermail/tuhs/2006-September/002692.html
- https://minnie.tuhs.org/pipermail/tuhs/2006-October/002693.html
- https://minnie.tuhs.org/pipermail/tuhs/2006-October/002694.html
- https://minnie.tuhs.org/pipermail/tuhs/2006-October/002695.html
- https://minnie.tuhs.org/pipermail/tuhs/2006-October/002701.html
- https://minnie.tuhs.org/pipermail/tuhs/2006-October/002695.html
- https://minnie.tuhs.org/pipermail/tuhs/2006-October/002702.html
In the w11a the `SPL` has 11/70 semantics in kernel mode, thus no
traps or interrupts, but in supervisor and user mode `SPL` really acts as
`NOOP`, so traps and interrupts are taken as for all other instructions.
**--> The w11a isn't bug compatible with the 11/70.**
- A 'red stack violation' loses PSW, a 0 is pushed onto the stack.
- The 'instruction complete flag' in `MMR0` is not implemented, it is
permanently '0', `MMR2` will not record vector addresses in case of a
vector fetch fault. Recovery of vector fetch faults is therefore not
possible, but only 11/45 and 11/70 supported this, no OS used that, and
it's even unclear whether it can be practically used.
- the 11/70 maps the 18 bit UNIBUS address space into the upper part of
the 22bit extended mode address space. With UNIBUS mapping enabled, this
allowed to access via 17000000:17757777 the memory exactly as a UNIBUS
device would see it. The w11a doesn't implement this remapping, an access
in the range 17000000:17757777 causes an NXM fault.
All four points relate to very 11/70 specific behavior, no operating system
All points relate to very 11/70 specific behavior, no operating system
depends on them, therefore they are considered acceptable implementation
differences.
### <a id="unspec">Differences in unspecified behavior cases between w11a and KB11-C (11/70)</a>
### Differences in unspecified behavior between w11a and KB11-C (11/70)
- [State of N and Z and registers after a `DIV` abort with `V=1`](w11a_diff_70_div_after_v1.md)
- The state of the N and Z condition codes is different after a DIV overflow.
The [1979 processor handbook](http://www.bitsavers.org/pdf/dec/pdp11/handbooks/PDP11_Handbook1979.pdf)
states on page 75 that the state of the N and Z condition codes is unspecified
when V=1 is set after a zero divide or an overflow condition.
After a DIV overflow, the w11 returns Z=0 and N based on the sign of the
full 32-bit result, as can be easily determined by xor'ing of the sign
bits of dividend and divisor.
This is also the most natural result, an overflow is certainly
not zero, and the sign is unambiguously determined by the inputs.
The SimH simulator also behaves like this. A real J11 and a real 11/70
can have N=0 even when dividend and divisor have opposite signs. And a
real 11/70 can have Z=1. Bottom line is, that the w11 differs from the
behavior of both the real 11/70 and the real J11 behavior.
- the state of the result registers is also unspecified after a DIV with V=1.
SimH and a real J11 never modify a register when V=1 is set. A real 11/70
and the w11 do, but under different conditions, and leave different values
in the registers.
- for gory details consult the [divtst](../tools/tests/divtst/README.md) code
and the log files for different systems in the
[data](../tools/tests/divtst/data/README.md) directory.
No software should depend on the unspecified behavior of the CPU, therefore
this is considered as an acceptable implementation difference.
No software should depend on unspecified behavior of the CPU, therefore
this is considered as acceptable implementation difference.
### Other differences between w11a and KB11-C (11/70)
- [Usage of 11/70 `SYSID` register](w11a_diff_70_sysid_usage.md)
### <a id="lim">Known limitations</a>
@@ -83,20 +35,3 @@ this is considered as acceptable implementation difference.
to a timeout, again mostly in test programs.
**--> a 'watch dog' mechanism will be added in a future version which
suspends the CPU when the server doesn't respond fast enough.**
### <a id="other">Other differences</a>
- usage of 11/70 SYSID register
- in real 11/70's sysid held the individual serial number
- in the w11 project sysid encodes the execution environment
- this allows to distinguish between real w11 and emulation under SimH or e11
- the SYSID is divided in fields
- bit 15: emulator flag (0=w11,1=emulator)
- bit 14:12: type, encodes w11 or emulator type
- bit 11:09: cpu number on 11/74 systems
- bit 8:0: serial number
- current assignments are
- w11a: 010123
- SimH: 110234
- e11: 120345