Thoughts on address space extensions

In a nearby thread @oldben mentioned the 8086’s segments, and the PDP-11’s bank switching - see below. It strikes me these are just two ways of getting over the limitations of a 16 bit address. Of course the VAX jumps out as an example of extended addressing (it’s in the name!), although I don’t know much about that.

It also feels true that many z80 micros added some kind of bank addressing, possibly in non-standard ways, and again, I don’t know if CP/M or other OSes offered a good way to make use of them. It feels like it was relatively rare to extend a 6502 machine in this way, although the '816 was a valiant effort to extend the architecture, but finding only limited volume application (IIGS, Communicator)

Any thoughts or examples?

Did any models of the PDP-11 use a split program/data scheme? I believe the Norsk Data ND-100 series did; that’s another way of breaking out of the limitations imposed by a 16-bit address space.

Well, “VAX” does stand for “Virtual Address eXtension,” and according to Wikipedia this was “because the VAX was seen as a 32-bit extension of the older 16-bit PDP-11 and because it was…an early adopter of virtual memory to manage this larger address space.” But they don’t have a reference for that, and it was just a new machine with a flat 32-bit address space, as opposed to any special trickery such as the split I+D that the PDP-11 used on some models. To my ear it the name sounds simply like adding virtual memory (i.e., the logical address in a program may be translated to a different physical address), which is orthogonal to size of address space.

It was not uncommon for Z80 machines to have ROM in the lower addresses (particularly at the reset vector 0000h), which was an area where CP/M required RAM, so plenty of machines such as the TRS-80 series had third-party RAM expansions that used bank switching to put RAM there in order to run CP/M. (Tandy itself also did this in the Model 4.) Even native machines designed to do nothing but run CP/M would usually use some sort of bank switching scheme to start with ROM there so that they could boot conveniently, I’d imagine.

MP/M may have made use of bank switching to help support multiple users. This no doubt would have been handled via some standard BIOS calls, allowing the vendor to supply the exact code to deal with switching banks.

No, adding bank-switching support to 6502 machines was extremely common, I would say.

It was designed in from the start on the original Apple II (1977) where the $C800-$CFFF range was bank-switched to allow all expansion cards to provide their own ROM in that area. The earlier Langauge Card adding Applesoft BASIC to the Apple II (probably 1978) banked between the motherboard ROM and the card’s ROM, and the later Language Card adding 16K of RAM (probably 1979, since it was designed for the II+) banked its additional RAM in as two 8K banks (onboard ROM and 8K of card RAM) at $E000-$FFFF and three 4K banks (onboard ROM and two 4K banks of RAM from the card) at $D000-$DFFF.

And of course the Commodore 64 had bank switching support to handle switching between the 64K of onboard RAM, 20K of onboard ROM and up to 16 KB of cartridge ROM. I’d imagine the C64 counts as very much not a “limited volume application.” :-)

You bet! As memory sizes grew DEC introduced a standard memory management scheme with varying capabilities depending on the machine. Several models supported virtual memory mapping and larger models (the 11/44 and 11/70, at least) also provided “split I+D,” reading program instructions from one address space mapping and data from another to allow total program sizes of up to 128 KB. (Something similar to split I+D, but just for loads and stores indexed by the Y register, was implemented by various vendors for the 6502, both first party and third party.)

I always thought that the Z8000 solution was rather awkward. It could either use plain 16 bit addresses or a 7 bit segment number and 16 bit offset (only available in the 48 pin Z8001, not the 40 pin Z8002). You needed a pair of 16 bit registers to store the segmented address, but one of them would only have the 7 bit segment number and the other 9 bits would be wasted.

You could just combine the 7 and 16 bits into a 23 bit address for an 8MB address space or use an external Z8010 memory management unit to have proper segments. In either case you can use the status lines to further split the address space into instructions, data, stack, i/o and so on.

Yes. The memory management unit on the 11/40 (and 34, 35, 45, etc.) could not do this, but the MMU in the 11/70 and other, larger machines could. The former MMU was also limited to 256 kB of total memory, while the latter could address 4 MB.

This was effected by loading all memory from Data space except for PC-relative loads, which used a different mapping for an Instruction space.

The ND-100 did that, as did the NORD-10 before it. A program could execute in 1-bank mode, or 2-bank mode. This was trivial to include in the design because they had memory management from the start: All memory accesses went through page tables, and the CPU could access two page tables at the same time. A bit in the CPU set the mode. In two-bank mode all memory references which were not P (program counter) relative would go through the “Alternative Page Table” (APT), while P-relative addressing (and instruction fetch) went through the “Normal Page Table” (PT). As these were 16-bit machines you got 2 x 64 kilowords of memory per program. The systems had 4 (later 16) page tables, so system-level programs and the operating system had access to more banks of virtual (or physical) memory by changing the Paging Control Register.

The programmer decided during compile and link time if the program should execute in 1-bank or 2-bank mode - you’d choose the latter when the program got larger. During link time you had to pick either the 1-bank or the 2-bank version of the runtime library (Fortran, Pascal, Planc etc had their own runtime libraries).

1 Like