Basically it's all about what component do when issues a refresh. which can be seen from (at least) two points of view:
The way RAM sees/handles refresh changed quite a bit over time.
Early RAM had only one kind of refresh: Access to a row would refresh it, no matter if read, write, or incomplete (RAS-only). External components had to supply row addresses and make sure that all rows were accessed within time.
Later, with the 4164 (IIRC), Auto-Refresh was introduced. Here each RAM already includes addressing logic to execute a refresh cycle, but the system still had to dedicate a memory cycle to execute it. It was initiated by pulling a special /REFRESH pin. Now external components only had to make sure that enough cycles were assigned within time.
With the introduction of 256 KiBit RAM (41256) that pin was reused to provide two more address bits, so it had to be signalled with an otherwise illegal combination of CAS-before-RAS.
Again Later (as well EDO?) Hidden Refresh was introduced. Essentially a combination of auto-refresh and extended data out timing. After issuing a regular RAS-CAS moderated request and while CAS was still held active to extend data output, RAS was assigned again issuing a hidden refresh cycle.
Finally, SDRAM not only changed the behaviour completely by being clocked, but as well introduced Self-Refreshduring power down - but SDRAM is a complete different story.
(For the question marks: Assignment is from memory, so maybe not exact with each generation)
All RAM needs some system side handling for refresh. This can be differentiated by what handling is needed as well as which component does it.
Since basic refresh is simply a full (or aborted) access, any system that guarantees that all rows will be accessed within the refresh time will work. So for a classic 4116 all 128 rows had to be addressed once, in no particular order, within two milliseconds. Possible ways were:
Continuous Access - his means the RAM is accessed in all (used) ROWs within refresh rime due normal operation. Video memory is often designed that way. It might need some careful assignment of address bits (*1), but removes all need for refresh hard- or software.
Burst Refresh - here a dedicated logic will take over RAM access and issue a series of consecutive refresh cycles. For a classic 200 ns 4116-3 this meant a burst 128 cycle, each 375 ns for a total of 48 µs. The advantage is that refresh logic, as well as bus arbitrating is rather simple and overhead is small. It may be the fastest possible refresh, as it does not need to follow the time frame of other system components (*2). On the backside it will the system will be not be able to do anything during this time, which might be a problem for real time/embedded applications.
A special sub case might software based burst refresh. This can be done for example by calling an interrupt every two milliseconds which gurantees to access every row once before returning. While this may sound like waste of time at first, like having a longish counter loop accessing each row once, it can easy be turned into an advantage. With using the lower 7 address bits as row (*1) this only required a series of 128 NOP, places in ROM, meaning only the interrupt invocation is an additional toll to be payed, compared to hardware burst, but will save quite some hardware (at very least two multiplexers and a counter). By making the routine do something useful instead of NOPs, this drawback can even be turned into an advantage. For example by operating a real time clock in these 128 bytes.
Cycle Stealing is an equally common implementation. Here the refresh logic will take over RAM access only for a single access, spreading out he disruption over the whole time frame. Over all performance is like burst mode but with timing delay reduced to a single cycle. On the backside it can't operate at faster speeds, so over all performance impact is always 128 system clock cycles.
A very prominent usage was with the original IBM PC. Here a timer let a DMA channel read from RAM in a repeated cycle. It fires every 15.1 µs i.e. every 72nd CPU-clock.
Hidden Refresh (not to be confused with hidden refresh within a RAM) is essentially like cycle stealing, except that only cycles are taken that are not used by other components (like CPU), thus not impacting performance. This of course only works with systems that have waste cycles.
Essentially this is the way the Z80 offers. During M1, when the instruction is decoded a refresh cycle is provided, hidden to execution and timing.
How Does That Come Together?
Well, that depends on each system's implementation.
- Who supplies Refresh addresses
- Who inserts refresh cycles
- How is this coordinated with other RAM users (most notably the CPU)
- How it's integrated into a systems clock framework
- and so on...
Ways to solve this are almost endless. It wouldn't make much sense to open up a list of various implementations.
*1 - Did anyone ever say that the logical (CPU) order of address bits must be the same for RAM?
*2 - For example when used in a system with a basic 2 MHz clock cycle, following the 2 MHz clock would mean that a burst would need 64 µs. With using its own clock during Refresh this can be tuned down to 48 µs.
*3 - It was also a source of early PC performance tweaking. Since memory access is two clocks every 72 clocks, refresh takes away 1/36th or 2.8%. Decreasing that (in steps of 3 clocks, as the timer is feed by 4.77 divided by 3)) increase the number of cycles the CPU could use. Going to 75 cycles is still within spec and gains 0.1%. Everything thereafter would leave the 2ms. Gains up to 1.5% could be realized with most machines. Not much, but hey, every bit counts.
Fun fact, on some (early) 286es these savings were seemingly dramatic when using Norton Index to check for system speed, A 12 MHz 286 would show up as 13-14 MHz. Except, this was an artefact of how the timing loop was interpreted no real speed gain.