[Partial answer about how it supports FPM RAM - I still need to look up the manual for timing details]
Support for (Fast) Page Mode RAM (*1)
The CPU supports N and S-cycles (ARM lingo) or Non-Sequential and Sequential cycles. The first access to any memory is always an N-cycle, optionally followed by S-cycles.
To handle this, the original ARM provided a signal SEQ
which would be pulled whenever the next instruction fetch was exactly one word ahead. Any memory controller could use this to keep the page open, enabling fast access. By being tied to only sequential fetches SEQ
will not be pulled for any (random) data access, jumps/branches or exceptions.
To do so, the ARM featured a somewhat odd design around the address register (*2). It's not the PC that gets incremented with each cycle, but the incrementer is assigned to the address register. It does an automatic increment after each access, and then loads into the register file to update the PC as well. Thus, the next address is available as early as possible. Each load instruction of the address register (from PC or data access) will now suppress setting SEQ
, resulting in a full addressing cycle.
It is safe to assume (*3) that the Load/Store Multiple instructions (LDM
/STM
) use the same addressing mechanic and so also benefit from S-cycles.
Basic Timing Structure for RAM Access
The ARM bus protocol is not designed around a fixed clock source, like 6502 or 8080/8086 style bus protocol, but requires clock signals (Phi1/Phi2) to be produced according to external requirements. Usually the memory controller handles this according to the detected cycle type (N or S), and the memory or I/O accessed.
This is done by extending PHI1/2, depending on the accessed memory (usually PHI1), to meet the device criteria. For third party access, like DMA or DRAM refresh, any conflicting CPU access was postponed by stopping the CPU until it was done. Of course stopping (on DRAM) was only possible during a N-cycle, as S-cycles require that no different address would be issued inbetween - as DMA or Refresh would do (*4).
It was also up to the memory controller to stretch PHI1 whenever an S-cycle crossed a page boundary and a new RAS cycle was needed. Outsourcing all memory handling was a great move to simplify the CPU design - after all, it's the memory subsystem as designed for each computer that knows best how to handle each memory or I/O type.
In addition the memory controller could terminate a memory cycle by pulling ABORT
. AFAIR this was only used for memory protection.
As a result a classic ARM CPU does not run at constant speed. 4 MHz is rather the maximum possible speed, not the effective. While the effect is more or less the same as with wait states it does, in theory allow a very fine granuality of speed adjustment. In reality ARM's memory controller worked with a basic clock of 16 MHz, making it not much different from how it would have worked on an 8086/286.
*1 - Or, more generically, for all devices that allow a shortened sequential access, like nibble-ROMs.
*2 - It's easy to see that the idea is inspired by the way the 6502 works.
*3 - I couldn't find any reference supporting this. Still, it would be stupid not to use it as it comes for free.
*4 - This again could create a possible memory fault if a program would do only continuous instruction fetch (S-cycles) without any jump or data access inbetween, as now the memory controller would not be able to do any refresh at all. (It would as well kill any DMA based video generation) It seems as if that risk was seen rather exotic :)