text: The following article is compiled from postings made to emutos-devel by
  Christian Zietz, and used with his permission.
  
  
  Memory bank detection on the ST and STe
  =======================================
  First, keep in mind that I figured this out from looking at the code
  and testing on my ST.  Jean-François del Nero helped out a lot by doing
  the STe tests, since I don't own an STe.
  
  Memory detection works individually for each bank by telling the MMU to
  assume 2 MB of RAM in that bank and then testing where patterns repeat.
  Now, the ST and the STE MMU differ on how they decode memory addresses.
  Thus, these repetitions occur at different memory locations.
  
  DRAM is addressed by rows and columns, so the MMU decodes a RAM address
  (21 bits, A20-A0, to address a maximum of 2 MB per bank) into row and
  column addresses.  As the RAM data bus is 16 bits wide, A0 doesn't need
  to be decoded.  In fact it's not even on the address bus.  So we use 20
  bits, 10 for row and 10 for column.
  
  ST memory bank detection
  ------------------------
  The address that is checked by the detection algorithm for a 512 kByte
  bank is 0x408 = 0 0000 0000 0100 0000 1000b.  The ST MMU (when set to
  2MB) does the following decode of that address (Rx and Cx are row and
  column address lines respectively):
  
  0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0
  ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
  C C C C C C C C C C R R R R R R R R R R X
  9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 X
  
  Now a 512 kByte bank does not use row and column address lines 9, so you
  can see that, if we have set the memory controller for a 2MB bank but
  really have a 512 kByte bank, 0x408 will map to 0x008.  This is exploited
  by the detection algorithm.
  
  STe memory bank detection
  -------------------------
  The address that is checked by the detection algorithm for a 512 kByte
  bank is 0x80008 = 0 1000 0000 0000 0000 1000b.  It is decoded differently
  though:
  
  0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
  ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
  C R C R C R C R C R C R C R C R C R C R X
  9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 X
  
  Again, C9 and R9 don't exist in a 512 kByte bank, hence in an STe
  0x80008 will map to 0x00008 during memory detection.
  
  
  
  Writing memory detection code that works on STs and STes
  ========================================================
  There are five possible different standard memory setups; each has a
  different wraparound address (always assuming that the memory controller
  has been set for a 2MB bank):
  1. STe w/128kB bank (if they exist): wraparound @ 0x40008
  2. ST w/128kB bank: wraparound @ 0x208
  3. STe w/512kB bank: wraparound @ 0x80008
     Note that this will also wraparound on an ST w/128kB bank, so we
     must test for the 128KB bank first
  4. ST w/512kB bank: wraparound @ 0x408
  5. ST or STe w/2MB bank: no wraparound
  
  Here are the details.  Don't forget: the wraparound occurs because the
  high order bits of row and column addresses are ignored on smaller banks.
  On a 512kB bank, bits R9/C9 are ignored; on a 128kB bank, bits R8-R9 and
  C8-C9 are ignored.
  
  Address 0x208
  -------------
  ST => will correctly wrap around at R8 when 128 kByte are installed
  0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0
  C C C C C C C C C C R R R R R R R R R R X
  9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 X
  
  STe => will not wrap around
  0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0
  C R C R C R C R C R C R C R C R C R C R X
  9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 X
  
  Address 0x408
  -------------
  ST => will correctly wrap around at R9 when 512 kByte are installed
  0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0
  C C C C C C C C C C R R R R R R R R R R X
  9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 X
  
  STE => will not wrap around
  0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0
  C R C R C R C R C R C R C R C R C R C R X
  9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 X
  
  Address 0x40008
  ---------------
  ST => will not wrap around
  0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
  C C C C C C C C C C R R R R R R R R R R X
  9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 X
  
  STe => will correctly wrap around at C8 when 128 kByte are installed
  0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
  C R C R C R C R C R C R C R C R C R C R X
  9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 X
  
  Address 0x80008
  ---------------
  ST => will falsely wrap around at C8 when 128 kByte are installed
  0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
  C C C C C C C C C C R R R R R R R R R R X
  9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 X
  
  STE => will correctly wrap around at R9 when 512 kByte are installed
  0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
  C R C R C R C R C R C R C R C R C R C R X
  9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 X
  
  
  
  Address decoding during normal operation
  ========================================
  After memory detection is finished, the MMU is configured to the actual
  RAM bank size present in the computer.  If there is less than 2 MB in a
  bank, the address decoding needs to be adapted.
  
  For example, only 19 bits (address lines A0-A18) are used to address
  512 kByte of RAM.  Furthermore, in a 512 kByte bank only row and column
  address lines 0-8 exist.
  
  The STe simply doesn't decode the topmost address lines (R9 and C9) in
  this case, so for example the address 0x40008 is still decoded as:
  
  1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
  C R C R C R C R C R C R C R C R C R X
  8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 X
  
  The ST however modifies its address decoding to account for the missing
  lines R9 and C9 as follows:
  
  1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
  C C C C C C C C C R R R R R R R R R X
  8 7 6 5 4 3 2 1 0 8 7 6 5 4 3 2 1 0 X
  
  Christian Zietz, May 2016
  