DIVMMC Automap Still Functional when CONMEM is Active
Reported by Garry in NextZXOS.
When automap is enabled and RST$08 is intercepted to service an esx api request, divmmc memory is enabled by automap to service the request. While the request is serviced an im1 interrupt can occur, causing code at 0x0038 to execute in divmmc memory. This is another automap entry point and again sets the internal automap bit. At the end of the isr, the automap must not be disabled in order to successfully return to the RST$08 code. However if the 0x0038 interrupt code is entered when the divmmc is not already enabled, the automap must be disabled at the end of the isr to successfully return. This problem is resolved by using late automap enable on address 0x0038. If divmmc is already enabled then code in the divmmc memory at 0x0038 will execute. If the divmmc is not already enabled then one byte is executed outside the divmmc memory at 0x0038 and further bytes are read from divmmc memory starting at 0x0039. This is enough to determine whether to disable automap at the end of the isr routine.
A further complication occurs if divmmc memory is enabled but not by the automap, instead by CONMEM. If an interrupt occurs while divmmc memory is paged in with CONMEM, the code at 0x0038 in divmmc memory will execute and the automap bit will be set. For a successful return from the CONMEM routine, the automap bit must be reset. So in the ISR with CONMEM set, the automap bit must be reset on exit. This contradicts what must be done if divmmc memory is present because of an automap enable. So code at 0x0038 must determine further if the CONMEM bit was set and if so, the isr exit must disable the automap and otherwise must not.
On an original divmmc interface, the port containing CONMEM is not readable so the resolution in the last paragraph is not available. There is no mention in sparse documentation if the automap is disabled while divmmc memory is active as it currently is not in the Next's implementation. If not, this may be a bug in the original divmmc interface.
On the Next, the divmmc is enhanced and allows automap entry points to be late or instant. An instant enable is meant to simplify code especially as the Next can have any sort of memory paged into the bottom 8K when an automap entry point is hit. The late entry point required above to resolve issues makes it difficult to allow any page to be present when the automap is triggered because, for example, address 0x0038 across all such pages must contain a predictable byte. So preferably a resolution can be found that does not require a late automap and can work on instant automap as well. Such a change should remain backwards compatible with remedies used with the original divmmc interface.
Possible resolutions:
-
When CONMEM is set, the automap is disabled. NextZXOS was running with automap enabled on ROM3 only so automap should not have been functional in the first place so that is one bug. When automap is always enabled, this must also hold.
-
Turn automap into a counter instead of a single bit flag.