20

I have an old Sharp PC-G830 pocket computer from the '80s that has 32K of RAM and 256K of ROM. I also have a simple single board computer I built with 128K of RAM and a few megabytes of ROM from a MicroSD card. Both of these computers, however, use a regular 40-pin Zilog Z80 processor with a 16-bit address bus and therefore a theoretical "limit" of 64K of memory. My understanding is that many other 8-bit computers like the Commodore 64 can utilize far above 64K of memory as well.

How do these computers accomplish this? How can my SBC address 128K of RAM even though it should theoretically only be able to address 64K? I have been scouring the internet for an answer for a few hours now and have yet to find an explanation I can wrap my head around. I have tried examining the schematics of computers that do this but I don't understand the theory behind the setup or how it works.

Any help is much appreciated, thank you for your time.

EDIT Another post was brought up in the comments and I would like to say that I am not looking for instructions on how to make my own MMU or a computer revolving around one. Judging by the comments on this post, the presented schematic is poorly designed and I am not looking to use it as a reference. Additionally, such a question is not related to retro computing and as such doesn't really belong on this forum. I am only looking for an explanation of how old, already designed computers accomplished the task of having more than 64K of total memory. The post that has been brought up does not explain how old computers addressed more than 64K of RAM and only pertains to new, theoretical and poorly made designs.

10
  • 25
    The term you want is 'bank switching'. Google it and/or have a read of en.wikipedia.org/wiki/Bank_switching. There's loads on this on the internet you can read up.
    – TonyM
    Jan 14 at 20:03
  • 1
    @TonyM Aah, thank you. The term "Memory banking" turns up very little on my search engine that is relevant to the topic. Bank switching definitely turns up more relevant info, thank you for telling me what I can search instead of just saying "Google it" :-)
    – Shades
    Jan 14 at 20:06
  • 1
    I find it interesting that you don't seem to be confused as to how it could access several megabytes of ROM. Surely any method of accessing ROM can be used to access RAM (from a practical point of view, slower access speed are accepted for accessing ROM, resulting in different methods actually being used, but from a purely theoretical point of view, is there a difference?) Jan 15 at 22:45
  • 1
    @Acccumulation From a theoretical viewpoint, banking ROM and RAM is the same. From a more practical viewpoint, ROM tends to contain more code than data (because data tends to change). And because you tend to know the code you put in ROM up-front, you can arrange it cleverly to achieve greater locality, thus less required bank switches (that need time)
    – tofro
    Jan 16 at 0:09
  • 3
    There is an effort to close this question as a duplicate. However, the old question has issues and is already closed. This question is better written and should be the one left open. Vote to leave this open.
    – DrSheldon
    Jan 16 at 17:08

5 Answers 5

30

I don't know details of the Sharp PC-G830 specifically but the technique used to address more than 64K with a 16-bit address bus is called "bank switching".

This involves setting up some portions of memory to be switchable via an I/O port line and then the application program organizes things in memory such that different sections can be switched in and out as needed.

It's not anywhere near as clean as having a larger address bus because you have to ensure that you don't switch a block of memory out that is being used or end up with a situation where you have to continually switch back and forth to complete the program.

Overall it was a scheme trying to allow more space in a system that was permitted by the architecture of the CPU. This was an interim step on the way to 16-bit CPUs such as the 8086 and 8088. Some would say that these two, for example, are really 8 bitters with bank switching built in and there is some truth to that. If you compare the 8086 architecture to say the 68000 architecture you can clearly see the difference.

8
  • 2
    My understanding then, is that the memory banks must be switched for whatever block you want to address. Wouldn't this add a lot of time to memory access if you had to switch banks a lot, or is the time the operation takes negligible? I'm just wondering since, say, my SBC has the full 64K and then some taken up by RAM wouldn't it have to switch banks every time it wishes to read data from ROM for the next instruction to execute? Sorry if this is a dumb question, I'm fairly new to designing hardware
    – Shades
    Jan 14 at 19:57
  • 7
    @Shades you’d organise your program so that it doesn’t need to switch banks very often. Some systems also had schemes where reads would read from ROM, and writes would write to RAM, so you could copy data into a bank with a ROM overlay while still running code in ROM (and then switch when you want to read from RAM). Jan 14 at 20:14
  • 1
    @StephenKitt: In some cases, one could also exploit the fact that a systems didn't fully decode I/O to allow zero-overhead bank switching. The menu program I did for the Atari 2600 cartridge "Stella's Stocking" did this. One many scan lines it needed direct access to about 3KB worth of wave tables and about 3K worth of graphics data; writes to the TIA at addresses $00-$3F when bank 14 was enabled switch to bank 15, and writes at $40-$7F when bank 15 was enabled would switch to bank 14, thus allowing bank-switching with literally zero overhead.
    – supercat
    Jan 14 at 22:04
  • 4
    An alternative scheme to bank switching is address latching, which permits more address bits than there are address pins. However, since the question said 16 address bits, not 16 address pins, that approach seems to be off the table here. (The two schemes are very closely related, differing in whether the "bank register" is itself mapped into the I/O space as its own location vs considered to be the upper bits of an pointer/index register used for indirect addressing.)
    – Ben Voigt
    Jan 14 at 22:19
  • 2
    Yet another schema is DMA transfer to and from external, non-addressable memory (e.g. Commodore REU)
    – tofro
    Jan 14 at 23:26
15

There are a number of approaches that can allow a CPU with a 16-bit address bus to address more than 64kBytes of memory:

  • Bank Switching - explained in another answer,basicaly switching for example 8- or 16-kBytes blocks back and forth into the addressable range, so in effect exchanging the blocks with ones that are currently paged in. Some computers could also bank in ROM, EPROM and Flash memory. The Cambridge Z88, for example uses banked RAM, EPROMs and Flash memory up to an overall amount of 4MB as mass storage medium directly addressed by the CPU and its banking chip (the blink) - So, you can "run" a program directly in-place "on" the storage media without "loading" it first, or access a "file" on the storage media by simply paging it in at a suitable address.
  • DMA transfer of "external" memory contents to and from the addressable address range (That is, for example, what the Commodore REU for the C128 and C64 did). That is, in effect, a really fast external RAM disk allowing to page in external memory contents into internal RAM (by transferring it byte-wise through the DMA chip). How fast the memory is accessible depends primarily on the achievable speed of the DMA chip employed. Later memory expansions (the GEOS RAM expansions) used banking as above.
2
  • 1
    re external memory -- the CDC 6000 had extended core storage, to and from which main core storage would be swapped out, using some sort of specialized "block move" instruction. Jan 14 at 23:35
  • 1
    Both of these were (as you know) still in use well into the ’90s. On DOS computers, EMS used bank-switching into 16K banks, and XMS did transfers. By then, the CPU was capable of 32-bit addressing if the OS supported it.
    – Davislor
    Jan 15 at 4:20
7

Another solution worth mentioning — although I doubt it was used by the systems you mention, and it merely allows addressing twice as much as 64K of memory — is "Split I&D", as rather famously used on later models of the PDP-11. A program could have 64K of memory for program text, and 64K of memory for data, for a total of 128K. The processor knew, based on whether it was fetching an instruction to execute or some data to work on, which half to access. In effect, the text-or-data distinction became a 17th address bit.

Although doubling the amount of memory you could access was a pretty big win, it placed limitations on certain exotic programming techniques, such as dynamically loaded (or self-modifying) code.

Split I&D is mentioned briefly (though not under that name) in the Wikipedia article on PDP-11 architecture.

(Fun historical anecdote: I heard a story, which I entirely believe, that when Unix was first modified to allow compiling and running split-I&D programs, some programs failed in strange ways. The problem was that in the initial implementation, variables were assigned starting at the beginning of data space, or address 0x0000. This meant that there was one poor variable whose address was the null pointer! This rather badly violated the fundamental notion that a null pointer is not the address of any object. The linker was modified to allocate a dummy, unused variable at address 0, and the problem went away, although the usable data space then dropped to 63.998K.)

10
  • 3
    Is "Split I&D" just a way to refer to a Harvard Architecture, or is there some subtle difference? Jan 15 at 13:51
  • 1
    @TobySpeight I don't think it's a Harvard Architecture, no. AIUI, a Harvard Architecture treated instructions and data completely separately, with separate pathways and storage areas for each. The PDP-11, OTOH, was a purely general von Neumann architecture, with main memory that held code or data. Split I&D was then this little wrinkle that squeezed a 17th address bit out of thin air. Jan 15 at 13:57
  • 1
    Thanks for the clarification. I think I understand it a little better (for a Z80 guy like myself, it would be akin to using M1 to identify instruction access, if all instructions were a single word). Jan 15 at 14:11
  • The point about Harvard is loading an instruction and it#s data in parallel, which needs two complete Independent busses operating in parallel. Splitting I&D is nust adding another address bit selecting between two spaces, one reserved for data the other for instructions.
    – Raffzahn
    Jan 15 at 14:13
  • 3
    @TobySpeight: It's Harvard in the sense that data and code are in separate address-spaces, and you can't use normal load/store instructions to access machine code. (e.g. to apply runtime relocations to absolute addresses in a page of machine code.) But normally Harvard also implies building the CPU to take advantage of that, as Raffzahn points out to allow independent parallel code-fetch and data load/store, making the Von Neumann bottleneck a little less bad. (Which this wouldn't do.) So it's the worst of both worlds, except for memory capacity. Jan 15 at 17:04
1

There's also the TI-99/4A way of accessing more ROM and RAM than there is address space. The TMS-9900 has a 15 bit address bus and could therefore only address 32768 16 bit words. When one looks at the memory map of the TI-99/4A one can see that the console can address (theoretically) up to 32KiB+256 RAM, 16KiB VRAM, 8KiB + 2x8KiB ROM, 24KiB + 16x40KiB GROM which represents up to 736 KiB.

How does it do it?

In a quite complicated and diverse manner

  • Direct access on 16 bit bus: 8K of ROM and 256 byte of RAM are directly mapped in the address range and are fast access.
  • Direct access on 8 bit bus: the 32k memory extension is directly mapped in the address space. Cartridge ROM can also be accessed via the 8 bit bus.
  • I/O memory access: the 16k video RAM is not directly accessible to the CPU and I/O operation on the video chip are necessary for access (unfortunately the base unit only had this memory to store the Basic programs, which crippled seriously the machine).
  • GROM access: GROM were special ROM chips sold by Texas Instrument that had a very different addressing scheme than normal ROMS. Normal ROM chips have a separate address and data bus with enough pins for addressing the capacity of the chip. GROM on the other hand have an 8 bit multiplexed bus and special pins and a read sequentially in a streaming way. Set start address and then read byte after byte, each read operation incrementing the address.

So, a very complex scheme with an architecture tuned for stream oriented processing with accessing more memory than the 64 KiB would allow, but a system that does not (initially) use bank switching.

0

I wrote a rather large program for a DEC PDP 11-70 at the end of the 1970s, and once it broke through the 64k barrier, I had to go to Overlays. This meant manually partitioning the program into pages, so that any one page was self consistent. Very tedious and error-prone. I don't recall if the entire 64k had to be swapped for a different one each time, or whether (say) a base 32k could stay resident while the other 32k swapped. All of that hassle went away when the company switched to a VAX.

1
  • It still had only 64KB virtual address space, and nothing "swapped" out; a new overlay (of exactly the size it was) would be read into the overlay area, or simply remapped there if you used memory-resident (PLAS) overlays.. But this is not really pertinent to the question, since the 11/70 had 22-bit physical addresses, i.e., a physical address space of 4MB. Jan 16 at 4:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.