It might be interesting to think of a way to extend the Spectrum's memory using a segmented model similar to the 80x86 rather than manually keeping track of pages.
By decoding the address bus having at least three segments, Data, Code and Stack operation could be relatively transparent. The memory window might live in the top 32k of RAM and the device would monitor the MREQ and M! signals and decode the instruction on the bus. It would need to provide some additional instructions by using empty areas in the Z80 instruction set to select or switch segments.
This would all require that the device be able to decode Z80 instructions to decide which segment was going to be used but once that's done everything else should fall into place. Luckily, the Z80 instruction set is relatively easy to decode and should require the minimum of logic.
The easiest way to test this out would be to rig up something that would decode a small subset of instructions and see if it works.
It also needs to be decided what kind of granularity the segments are going to have. In the x86 it's 16 bytes, which extends the addressing range to 20 bits or one megabyte. Will that be enough for the Spectrum, or should we make it a definable register in the device?
Starting off I would stick with the code, data, stack and extended segment registers; CS, DS, SS and ES but we could always define additional ones if it was useful.
The plan then would be to be able to extend the assembler mnemonics so that you could write code such as the following (assuming the segments were aligned on 16-byte boundaries):
Block move and related instructions would by default use ES as the source segment and DS as the destination segment, with HL as the source offset and DE as the destination offset as normal.
Theory of operation: