Guest User

ram.c

a guest
Mar 12th, 2013
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.48 KB | None | 0 0
  1. //============================================================================//
  2. //                                                                            //
  3. //  Copyright 2007 Rick "Lick" Wong                                           //
  4. //                                                                            //
  5. //  This library is licensed as described in the included readme.             //
  6. //                                                                            //
  7. //============================================================================//
  8.  
  9. #include "ram.h"
  10.  
  11. vu16 *_writable_cartridge_unlock(void);
  12. void _writable_cartridge_lock(void);
  13. vu16 *_fail_unlock();
  14. void _fail_lock();
  15.  
  16. u32 ram_is_locked=0;
  17.  
  18. //===================================//
  19. //                                   //
  20. //       Device Ram Drivers !        //
  21. //                                   //
  22. //===================================//
  23.  
  24. //========================
  25. vu16 *_sc_unlock ()
  26. //========================
  27. {
  28.     *(vu16*)0x9FFFFFE = 0xA55A;
  29.     *(vu16*)0x9FFFFFE = 0xA55A;
  30.     *(vu16*)0x9FFFFFE = 0x5; // RAM_RW
  31.     *(vu16*)0x9FFFFFE = 0x5;
  32.  
  33.     return (vu16*)0x8000000;
  34. }
  35.  
  36. //========================
  37. void _sc_lock ()
  38. //========================
  39. {
  40.     *(vu16*)0x9FFFFFE = 0xA55A;
  41.     *(vu16*)0x9FFFFFE = 0xA55A;
  42.     *(vu16*)0x9FFFFFE = 0x3; // MEDIA
  43.     *(vu16*)0x9FFFFFE = 0x3;
  44. }
  45.  
  46. //========================
  47. vu16 *_m3_unlock ()
  48. //========================
  49. {
  50.     u32 mode = 0x00400006; // RAM_RW
  51.     vu16 tmp;
  52.     tmp = *(vu16*)0x08E00002;
  53.     tmp = *(vu16*)0x0800000E;
  54.     tmp = *(vu16*)0x08801FFC;
  55.     tmp = *(vu16*)0x0800104A;
  56.     tmp = *(vu16*)0x08800612;
  57.     tmp = *(vu16*)0x08000000;
  58.     tmp = *(vu16*)0x08801B66;
  59.     tmp = *(vu16*)(0x08000000 + (mode << 1));
  60.     tmp = *(vu16*)0x0800080E;
  61.     tmp = *(vu16*)0x08000000;
  62.     tmp = *(vu16*)0x080001E4;
  63.     tmp = *(vu16*)0x080001E4;
  64.     tmp = *(vu16*)0x08000188;
  65.     tmp = *(vu16*)0x08000188;
  66.  
  67.     return (vu16*)0x8000000;
  68. }
  69.  
  70. //========================
  71. void _m3_lock ()
  72. //========================
  73. {
  74.     u32 mode = 0x00400003; // MEDIA
  75.     vu16 tmp;
  76.     tmp = *(vu16*)0x08E00002;
  77.     tmp = *(vu16*)0x0800000E;
  78.     tmp = *(vu16*)0x08801FFC;
  79.     tmp = *(vu16*)0x0800104A;
  80.     tmp = *(vu16*)0x08800612;
  81.     tmp = *(vu16*)0x08000000;
  82.     tmp = *(vu16*)0x08801B66;
  83.     tmp = *(vu16*)(0x08000000 + (mode << 1));
  84.     tmp = *(vu16*)0x0800080E;
  85.     tmp = *(vu16*)0x08000000;
  86.     tmp = *(vu16*)0x080001E4;
  87.     tmp = *(vu16*)0x080001E4;
  88.     tmp = *(vu16*)0x08000188;
  89.     tmp = *(vu16*)0x08000188;
  90. }
  91.  
  92. //========================
  93. vu16 *_opera_unlock ()
  94. //========================
  95. {
  96.     *(vu16*)0x8240000 = 1;
  97.  
  98.     return (vu16*)0x9000000;
  99. }
  100.  
  101. //========================
  102. void _opera_lock ()
  103. //========================
  104. {
  105.     *(vu16*)0x8240000 = 0;
  106. }
  107.  
  108.  
  109. //========================
  110. vu16 *_g6_unlock ()
  111. //========================
  112. {
  113.     u32 mode = 6; // RAM_RW
  114.     vu16 tmp;
  115.     tmp = *(vu16*)0x09000000;
  116.     tmp = *(vu16*)0x09FFFFE0;
  117.     tmp = *(vu16*)0x09FFFFEC;
  118.     tmp = *(vu16*)0x09FFFFEC;
  119.     tmp = *(vu16*)0x09FFFFEC;
  120.     tmp = *(vu16*)0x09FFFFFC;
  121.     tmp = *(vu16*)0x09FFFFFC;
  122.     tmp = *(vu16*)0x09FFFFFC;
  123.     tmp = *(vu16*)0x09FFFF4A;
  124.     tmp = *(vu16*)0x09FFFF4A;
  125.     tmp = *(vu16*)0x09FFFF4A;
  126.     tmp = *(vu16*)(0x09200000 + (mode << 1));
  127.     tmp = *(vu16*)0x09FFFFF0;
  128.     tmp = *(vu16*)0x09FFFFE8;
  129.  
  130.     return (vu16*)0x8000000;
  131. }
  132.  
  133. //========================
  134. void _g6_lock ()
  135. //========================
  136. {
  137.     u32 mode = 3; // MEDIA
  138.     vu16 tmp;
  139.     tmp = *(vu16*)0x09000000;
  140.     tmp = *(vu16*)0x09FFFFE0;
  141.     tmp = *(vu16*)0x09FFFFEC;
  142.     tmp = *(vu16*)0x09FFFFEC;
  143.     tmp = *(vu16*)0x09FFFFEC;
  144.     tmp = *(vu16*)0x09FFFFFC;
  145.     tmp = *(vu16*)0x09FFFFFC;
  146.     tmp = *(vu16*)0x09FFFFFC;
  147.     tmp = *(vu16*)0x09FFFF4A;
  148.     tmp = *(vu16*)0x09FFFF4A;
  149.     tmp = *(vu16*)0x09FFFF4A;
  150.     tmp = *(vu16*)(0x09200000 + (mode << 1));
  151.     tmp = *(vu16*)0x09FFFFF0;
  152.     tmp = *(vu16*)0x09FFFFE8;
  153. }
  154.  
  155. //========================
  156. vu16 *_ez_unlock ()
  157. //========================
  158. {
  159.     return (vu16*)0x8400000;
  160. }
  161.  
  162. //========================
  163. void _ez_lock ()
  164. //========================
  165. {
  166. }
  167.  
  168.  
  169. //===================================//
  170. //                                   //
  171. //              Ram API !            //
  172. //                                   //
  173. //===================================//
  174.  
  175. static vu16* (*_unlock) () = 0;
  176. static void  (*_lock) () = 0;
  177. static u32  _size = 0;
  178. static RAM_TYPE _type = DETECT_RAM;
  179. const char *_types[] = {"Unknown", "Supercard", "M3", "Opera", "G6", "EZ"};
  180.  
  181.  
  182. //==========================================================
  183. static bool  _ram_test ()
  184. //==========================================================
  185. {
  186.     vu16 *ram = _unlock();
  187.    
  188.     u16 oldram = ram[0];
  189.  
  190.     ram[0] = 0x1234;
  191.     if(ram[0] == 0x1234)        // test writability
  192.     {
  193.         _lock();
  194.  
  195.         ram[0] = 0x4321;
  196.         if(ram[0] != 0x4321)    // test non-writability
  197.         {
  198.             return true;
  199.         }
  200.         ram[0]=oldram;
  201.     }
  202.  
  203.     return false;
  204. }
  205.  
  206. //==========================================================
  207. static bool  _ram_test_nolock ()
  208. //==========================================================
  209. {
  210.     vu16 *ram = _unlock();
  211.    
  212.     u16 oldram = ram[0];
  213.  
  214.     ram[0] = 0x1234;
  215.     if(ram[0] == 0x1234)        // test writability
  216.     {
  217.         ram[0]=oldram;
  218.         return true;
  219.     }
  220.  
  221.     return false;
  222. }
  223.  
  224.  
  225. // Based on DSLinux Amadeus' detection
  226. //==========================================================
  227. static bool  _ram_test_ez ()
  228. //==========================================================
  229. {
  230.     vu16 *ram;
  231.  
  232.     *(vu16*)0x9FE0000 = 0xD200; // SetRompage (OS mode)
  233.     *(vu16*)0x8000000 = 0x1500;
  234.     *(vu16*)0x8020000 = 0xD200;
  235.     *(vu16*)0x8040000 = 0x1500;
  236.     *(vu16*)0x9880000 = 0x8000;
  237.     *(vu16*)0x9FC0000 = 0x1500;
  238.  
  239.     *(vu16*)0x9FE0000 = 0xD200; // OpenNorWrite
  240.     *(vu16*)0x8000000 = 0x1500;
  241.     *(vu16*)0x8020000 = 0xD200;
  242.     *(vu16*)0x8040000 = 0x1500;
  243.     *(vu16*)0x9C40000 = 0x1500;
  244.     *(vu16*)0x9FC0000 = 0x1500;
  245.  
  246.  
  247.     ram = (vu16*)0x08400000;
  248.  
  249.     ram[0] = 0x1234;
  250.     if(ram[0] == 0x1234)        // test writability
  251.     {
  252.         ram = (vu16*)0x08000000;
  253.  
  254.         ram[0] = 0x4321;
  255.         if(ram[0] != 0x4321)    // test non-writability
  256.         {
  257.             return true;
  258.         }
  259.     }
  260.  
  261.     *(vu16*)0x9FE0000 = 0xD200; // CloseNorWrite
  262.     *(vu16*)0x8000000 = 0x1500;
  263.     *(vu16*)0x8020000 = 0xD200;
  264.     *(vu16*)0x8040000 = 0x1500;
  265.     *(vu16*)0x9C40000 = 0xD200;
  266.     *(vu16*)0x9FC0000 = 0x1500;
  267.  
  268.     *(vu16*)0x9FE0000 = 0xD200; // SetRompage (352)
  269.     *(vu16*)0x8000000 = 0x1500;
  270.     *(vu16*)0x8020000 = 0xD200;
  271.     *(vu16*)0x8040000 = 0x1500;
  272.     *(vu16*)0x9880000 = 352;
  273.     *(vu16*)0x9FC0000 = 0x1500;
  274.  
  275.     *(vu16*)0x9FE0000 = 0xD200; // OpenNorWrite
  276.     *(vu16*)0x8000000 = 0x1500;
  277.     *(vu16*)0x8020000 = 0xD200;
  278.     *(vu16*)0x8040000 = 0x1500;
  279.     *(vu16*)0x9C40000 = 0x1500;
  280.     *(vu16*)0x9FC0000 = 0x1500;
  281.  
  282.     ram = (vu16*)0x08400000;
  283.    
  284.     ram[0] = 0x1234;
  285.     if(ram[0] == 0x1234)        // test writability
  286.     {
  287.         return true;
  288.     }
  289.    
  290.     return false;
  291. }
  292.  
  293.  
  294. //==========================================================
  295. static void  _ram_precalc_size ()
  296. //==========================================================
  297. {
  298.     vu16 *ram;
  299.     if(_unlock == 0 || _lock == 0)
  300.         return;
  301.        
  302.     ram = _unlock();
  303.     _size = 0;
  304.  
  305.     ram[0] = 0x2468;
  306.     while(ram[_size] == 0x2468)
  307.     {
  308.         ram[_size] = 0;
  309.         _size += 512;
  310.         ram[_size] = 0x2468;
  311.     }
  312.     _size<<=1;
  313.  
  314.     _lock();
  315. }
  316.  
  317.  
  318. //==========================================================
  319. bool  ram_init (RAM_TYPE type)
  320. //==========================================================
  321. {
  322. //    sysSetBusOwners(BUS_OWNER_ARM9, BUS_OWNER_ARM9);
  323.  
  324.     switch(type)
  325.     {
  326.         case SC_RAM:
  327.         {
  328.             _unlock = _sc_unlock;
  329.             _lock   = _sc_lock;
  330.             _type   = SC_RAM;
  331.         }
  332.         break;
  333.  
  334.         case M3_RAM:
  335.         {
  336.             _unlock = _m3_unlock;
  337.             _lock   = _m3_lock;
  338.             _type   = M3_RAM;
  339.         }
  340.         break;
  341.  
  342.         case OPERA_RAM:
  343.         {
  344.             _unlock = _opera_unlock;
  345.             _lock   = _opera_lock;
  346.             _type   = OPERA_RAM;
  347.         }
  348.         break;
  349.  
  350.         case G6_RAM:
  351.         {
  352.             _unlock = _g6_unlock;
  353.             _lock   = _g6_lock;
  354.             _type   = G6_RAM;
  355.         }
  356.         break;
  357.  
  358.         case EZ_RAM:
  359.         {
  360.             _unlock = _ez_unlock;
  361.             _lock   = _ez_lock;
  362.             _type   = EZ_RAM;
  363.         }
  364.         break;
  365.  
  366.         case DETECT_RAM:
  367.         default:
  368.         {
  369.             _unlock = _writable_cartridge_unlock;
  370.             _lock   = _writable_cartridge_lock;
  371.             _type   = RAM_CART;
  372.  
  373.             //If we have a RAM cart (like VBA_romwrite), immediately check if it's writable
  374.             if (_ram_test_nolock())
  375.             {
  376.                 break;
  377.             }
  378.                
  379.            
  380.            
  381.             // try ez
  382.             _unlock = _ez_unlock;
  383.             _lock   = _ez_lock;
  384.             _type   = EZ_RAM;
  385.            
  386.             if(_ram_test_ez())
  387.             {
  388.                 break;
  389.             }
  390.  
  391.             // try supercard
  392.             _unlock = _sc_unlock;
  393.             _lock   = _sc_lock;
  394.             _type   = SC_RAM;
  395.  
  396.             if(_ram_test())
  397.             {
  398.                 break;
  399.             }
  400.  
  401.             // try m3
  402.             _unlock = _m3_unlock;
  403.             _lock   = _m3_lock;
  404.             _type   = M3_RAM;
  405.  
  406.             if(_ram_test())
  407.             {
  408.                 break;
  409.             }
  410.  
  411.             // try opera
  412.             _unlock = _opera_unlock;
  413.             _lock   = _opera_lock;
  414.             _type   = OPERA_RAM;
  415.  
  416.             if(_ram_test())
  417.             {
  418.                 break;
  419.             }
  420.  
  421.             // try g6
  422.             _unlock = _g6_unlock;
  423.             _lock   = _g6_lock;
  424.             _type   = G6_RAM;
  425.            
  426.             if(_ram_test())
  427.             {
  428.                 break;
  429.             }
  430.  
  431.             // fail
  432.             _unlock = _fail_unlock;
  433.             _lock   = _fail_lock;
  434.             _type   = DETECT_RAM;
  435.  
  436.             return false;
  437.         }
  438.         break;
  439.     }
  440.    
  441. //    _ram_precalc_size();
  442.    
  443.     return true;
  444. }
  445.  
  446.  
  447. //==========================================================
  448. RAM_TYPE   ram_type ()
  449. //==========================================================
  450. {
  451.     return _type;
  452. }
  453.  
  454.  
  455. //==========================================================
  456. const char*   ram_type_string ()
  457. //==========================================================
  458. {
  459.     return _types[(int)_type];
  460. }
  461.  
  462.  
  463. //==========================================================
  464. u32   ram_size ()
  465. //==========================================================
  466. {
  467.     return _size;
  468. }
  469.  
  470.  
  471. //==========================================================
  472. vu16* ram_unlock ()
  473. //==========================================================
  474. {
  475. //    sysSetBusOwners(BUS_OWNER_ARM9, BUS_OWNER_ARM9);
  476.  
  477.     ram_is_locked=0;
  478.  
  479.     if(_unlock)
  480.         return _unlock();
  481.     return 0;
  482. }
  483.  
  484.  
  485. //==========================================================
  486. void  ram_lock ()
  487. //==========================================================
  488. {
  489. //    sysSetBusOwners(BUS_OWNER_ARM9, BUS_OWNER_ARM9);
  490.  
  491.     ram_is_locked=1;
  492.  
  493.     if(_lock)
  494.         _lock();
  495. }
  496.  
  497.  
  498. vu16 *_writable_cartridge_unlock()
  499. {
  500.     return (vu16*)0x08000000;
  501. }
  502.  
  503. void _writable_cartridge_lock()
  504. {
  505.    
  506. }
  507.  
  508. vu16 *_fail_unlock()
  509. {
  510.     return (vu16*)0x02000000;
  511. }
  512.  
  513. void _fail_lock()
  514. {
  515.    
  516. }
Advertisement
Add Comment
Please, Sign In to add comment