I'm trying to build a game console from scratch (as an exercise, not necessarily for practicality).
What I want to do is to have multiple "CPUs", in this case one being the Main CPU and the other one controlling the controller ports. My idea is to use shared RAM, where the "Interface Controller" CPU is polling the controller ports and then writing the results to RAM, where the "Main" CPU can read it.
What I'm trying to figure out is how I would connect the RAM to the system – I doubt I can just connect the address/data pins of both CPUs to the same pin on the RAM chip directly, but I'm not familiar with what arbitration methods exist.
What is commonly done here? Is there some kind of "intermediary" chip that serves as a "switch" to select which CPU is connected to the RAM at any given time? Or maybe some kind of "buffer" that the Interface CPU writes into, and which is then somehow flushed into the RAM? Or is there a simple "Bus" that allows multiple components to access it? (I'm thinking of SPI here, with it's chip select/SS pin)
Assume a system that's using simple CPUs (e.g., Z80, 6502) and SRAM (e.g., Cypress CY62256), so nothing that supports sophisticated protocols out of the box. And if it helps, one CPU would only ever write and one only ever read.
Best Answer
In general: There are many ways and it's not trivial. You will need to design something yourself.
If the amount of data is very small (like controller inputs) you could use a register which stores the latest data. The input side of the register connects (somehow - you'll need to design some logic) to the interface CPU's memory bus, and the output side connects (somehow) to the main CPU's memory bus. Apart from this register, the two CPUs have entirely separate memory. Done. (It seems like a waste of a CPU though)
Most CPUs don't access the memory every single cycle, so you can make them take turns. When the main CPU wants to access memory, let it access the memory bus. When the interface CPU wants to access memory and the main CPU doesn't, let it access the memory bus. When the interface CPU wants to access memory and the main CPU does, pause the interface CPU. You'll still need to design some logic.
You could give each CPU its own memory bus, but design some logic (see the pattern?) to allow the main CPU to access some of the interface CPU's memory (or vice versa). You could pause the interface CPU whenever the main CPU accesses its memory (easier) or only when the main CPU tries to access the shared memory at the same time as the interface CPU (harder, but still doable).
In any case, the specific logic circuit can't be designed without knowing all the details of how the RAM and CPUs need to connect. "Assume we have a Z80 or 6502" is not enough information to actually design the circuit. We can only make approximations and draw block diagrams.
Here are some general tips: