4-mb Ram Cart

Is there any way to incorporate in to home dev. I'm planning to work on a ngpc emu but I want to use the whole system ram for the emu and other stuff and the 4 mb ram cart for roms, but i dont want to make it if i cant use the 4-mb ram cart.
 
Just check for the presence of the cart (if you want to make it easy for people with the faulty carts sold now, check both the cart id and the amount of memory present) then just use it.
 
Originally posted by black@Jun 30, 2004 @ 02:22 AM

...I want to use the whole system ram for the emu and other stuff and the 4 mb ram cart for roms...

Hey, what a great idea!

There is the SEGA_MEM library, for which you define an area of RAM (Cartridge, ...) and then you can use this area for dynamic allocation via malloc. The library has it's own malloc, free,... functions. And you can only define one such area. I doubt you would need multiple areas on Saturn, but little modification could overcome this.
 
1. How to use External RAM cartridge

2. How to use half of CPU internal cache as RAM

1. Based on the ST-TECH-47.pdf manual and SCU user manual for memory mapping, i coded a sample to init the external RAM Cartridge:

Code:
int initCartridge(unsigned char cs)

{

  Uint32 id, setReg, *ptr, i, size, ok;

//!!!!!! on real Saturn, it doesn't go beyound this check

// on emu, always reports id == 0

  // cartridge initialization: as in ST-TECH-47.pdf

  // 1. verify cartridge id

  // 5A - 8 MB

  // 5C - 32 MB

  id = *((Uint32 *)0x24ffffff);

  if(id == 0x5a) {

    slPrint("8 MB RAM cart detected!", slLocate(2,5));

  } else if(id == 0x5c) {

    slPrint("32 MB RAM cart detected!", slLocate(2,5));

  } else {   

    // 2. prompt proper connection

    slPrint("There is no external RAM cartridge!", slLocate(2,5));

    slPrintHex(id, slLocate(5,6));

//    return 0;

  }

  slPrintHex(id, slLocate(5,6));

  // 3. write 1 to initialize

  *((Uint32 *)0x257efffe) = 1;

  // 4. set A-bus set and refresh registers

  setReg = 0;

  if(cs == 0) {

    // set cs0 for 32MBit

    setReg |= 1 << 29; // After-READ precharge insert bit

    ptr = (Uint32 *)0x22000000;

    size = 1048576;

  } else {

    // set cs1 for 16MBit ??

    setReg |= 1 << 28; // external wait effective bit

    ptr = (Uint32 *)0x24000000;

    size = 262144;

  }

  setReg |= 3 << 24; // Burst cycle wait number

  setReg |= 3 << 20; // Normal cycle wait number

  *((Uint32 *)0x25fe0080) = setReg;

  // 5. verify data before proceeding

    // write

  for(i = 0; i < size; i++)

    *(ptr++) = i;

    // read

  ok = 1;

  for(i = 0; i < size; i++) {

    if(*(ptr++) != i) {

      ok = 0;

    }  

  } 

    

  slPrint("verifying RAM cartridge:", slLocate(2,7));

  slPrintHex(ok, slLocate(5,8)); 

                 

  return ok;

}

Now the problem is that it freezes on real Saturn and always reports id = 0 in Satourne emu.

Furthermore, the manual states that area 0x22400000 - 0x227FFFFF is allocated to the cartridge, but I cannot find this elsewhere, it's not on SCU's memory map....

2. I know how to set 2kB of the 4kB cpu cache as local RAM:

If the cache is set to 2-way mode(instead of 4-way mode), it is set to 2kB RAM, too. The SEGA_CSH library can be taken to do this: CSH_SET_WAY_MODE( CSH_2WAY )

But I don't know how to address this RAM directly!

Now that I had another look into CSH_MAIN.C of SBL's cache lib, I see that CSH_init() writes zeros to locations after 0x60000000 and performs CSH_SET_ACS_WAY(way) 4 times.

Could this have something to do with the RAM location?
 
Reading a 32-bit int from 0x24ffffff isn't going to net you more than an alignment exception. The memory range in the cartridge manual is the correct one, and the SH7604 manual will have info on using the cache as RAM.
 
Furthermore, the manual states that area 0x22400000 - 0x227FFFFF is allocated to the cartridge, but I cannot find this elsewhere, it's not on SCU's memory map....

Cartridges are mapped to the "A-Bus CS0" (normally ROM/RAM) and "A-Bus CS1" (normally cart ID) regions.
 
I'm very, very happy to say:

Both problems are solved! :banana :cheers

(thanks antime and ExCyber!)

1. checking for, initializing and using extended RAM carts:

Code:
//  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;

    }    

}

2. initializing and using half of CPU's Cache as RAM:

init:

CSH_SET_WAY_MODE( CSH_2WAY )

Edit: better use CSH_Init(CSH_2WAY), it cares about cache disabling and stuff

now ways 0, 1 are RAM,

ways 2,3 mixed instruction/data cache memory

use:

0xC0000000

way 0

0xC00003FF

0xC0000400

way 1

0xC00007FF

Wow, I'm very excited about that! Now borders are shifted back...

Edit: look at 2.
 
Back
Top