// Â RB_initRAMCart(Uint8 cs, Uint8 quiet)
// Â - checks for present RAM cart, inits and verifies it
//
// Â inputs:
//    cs      -  select whether to set CS0 or CS1 space
// Â Â Â Â Â Â Â Â Â Â Â (both works, don't know where the difference is) Â
//    quiet    -  don't print messages
//
// Â returns:
//    cartridge id   -  on success
// Â Â Â Â Â Â Â Â Â Â Â Â Â (8MB: 0x5a or 32MB: 0x5c)
// Â Â Â -1 Â Â Â Â Â Â Â - Â no cart
// Â Â Â -2 Â Â Â Â Â Â Â - Â data verify failed
Sint16 RB_CartRAM_init(Uint8 cs, Uint8 quiet)
{
  Uint32 setReg, refReg, *DRAM0, *DRAM1, DRAMsize, i, ok;
  Uint8 id;
  // cartridge initialization: as in ST-TECH-47.pdf
  // 1. verify cartridge id
  // 5A - 8 MB
  // 5C - 32 MB
  //! is last byte of A-BUS CS1 area
  id = *((Uint8 *)0x24ffffff);
  if(id == 0x5a) {
    DRAMsize = 0x80000;
    if(quiet == 0)
      slPrint("8 MB RAM cart detected!", slLocate(2,5));
  } else if(id == 0x5c) {
    DRAMsize = 0x200000;
    if(quiet == 0)
      slPrint("32 MB RAM cart detected!", slLocate(2,5));
  } else {   Â
    // 2. prompt proper connection
    if(quiet == 0) {
      slPrint("The extended RAM", slLocate(2,5));
      slPrint("cartridge is not", slLocate(2,6));
      slPrint("inserted properly.", slLocate(2,7));
      slPrint("Please turn off", slLocate(2,9));
      slPrint("power and reinsert", slLocate(2,10));
      slPrint("the extended RAM", slLocate(2,11));
      slPrint("cartridge.", slLocate(2,12));
    }  Â
    return -1;
  }
  // 3. write 1 to initialize
  // is at the end of A-BUS Dummy area
  // !!! word format !!! (but what is meant?)
  *((Uint16 *)0x257efffe) = 1;
 Â
  // 4. set A-bus set and refresh registers
  setReg = refReg = 0;
  if(cs == 0) {
    // set cs0 for 32MBit
    setReg |= 1 << 29;  // After-READ precharge insert bit
    setReg |= 3 << 24;  // Burst cycle wait number
    setReg |= 3 << 20;  // Normal cycle wait number
  } else {
    // set cs1 for 16MBit ??
    setReg |= 1 << 28;  // external wait effective bit
    setReg |= 15 << 24; // Burst cycle wait number
    setReg |= 15 << 20; // Normal cycle wait number
  }
  *((Uint32 *)0x25fe00B0) = setReg;
    // A-Bus refresh register
  refReg |= 1 << 4;    // A-Bus refresh enable bit
      // I've just take this value
      // see SCU user manual for value range
  refReg |= 1;       // A-Bus refresh cycle wait
  *((Uint32 *)0x25fe00B8) = refReg;
 Â
  // 5. verify data before proceeding
    // cache-through DRAM0 and DRAM1
  DRAMsize >>= 2; // byte length -> longword length
  DRAM0 = (Uint32 *)0x22400000;
  DRAM1 = (Uint32 *)0x22600000;
    // write
  for(i = 0; i < DRAMsize; i++) {
    *(DRAM0 + i) = i;
    *(DRAM1 + i) = DRAMsize - 1 - i;
  }  Â
    // read
  ok = 1;
  for(i = 0; i < DRAMsize; i++) {
    if(*(DRAM0 + i) != i) {
      were_here("DRAM0 %i != %i", *(DRAM0 + i), i);
      ok = 0;
    }  Â
    if(*(DRAM1 + i) != (DRAMsize - 1 - i)) {
      were_here("DRAM1 %i != %i", *(DRAM1 + i), (DRAMsize - 1 - i));
      ok = 0;
    }  Â
  }
  Â
  if(ok == 1) {            Â
    if(quiet == 0)
      slPrint("verifying RAM cart OK!", slLocate(2,7));
    return id;
  } else {
    if(quiet == 0)
      slPrint("verifying RAM cart FAILED!", slLocate(2,7));
    return -2;
  }  Â
}