Guest User

libgbpak_upload_save

a guest
Jun 23rd, 2014
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 19.62 KB | None | 0 0
  1. /*
  2.  * libgbpak v0.2 beta for libdragon
  3.  * by saturnu
  4.  *
  5.  * TODO: testing mbc1 above bank 31 and mbc2-mbc5
  6.  * TODO: reset high bits mbc1 mbc5 if not reading whole rom in serial
  7.  * TODO: rtc/rumble support
  8.  * mapper info: http://gbdev.gg8.se/wiki/articles/Memory_Bank_Controllers
  9.  * libdragon: https://github.com/DragonMinded/libdragon
  10.  */
  11.  
  12.  
  13. #include <stdio.h>
  14. #include <malloc.h>
  15. #include <string.h>
  16. #include <stdint.h>
  17. #include <libdragon.h>
  18. #include "libgbpak.h"
  19.  
  20. //ed64 header
  21. #include "sys.h"
  22.  
  23.  
  24. uint8_t data[32];
  25. cart gbcart;
  26.  
  27.  
  28.  
  29. int copy_gbRom_toRAM(uint8_t *rom_data){
  30.    
  31.     uint8_t rdata[32];
  32.  
  33.     unsigned long addr=0xC000;
  34.     unsigned long sd_offset=0x00;
  35.     int tmp=0x00;
  36.    
  37.     //copy banks to sdram
  38.     for(int bankc=0; bankc < gbcart.rombanks; bankc++){ //bank count
  39.    
  40.     //mbc1 exceptions
  41.     if(gbcart.mapper==GB_MBC1 && (bankc==0x20 || bankc==0x40 || bankc==0x60))
  42.     bankc++;
  43.  
  44.  
  45.     //get power status 0=off 1=on
  46.     if(_get_gbPower()!=1)
  47.     return -4;
  48.  
  49.     //get access mode
  50.     int as=_get_gbAccessState();
  51.  
  52.     //int 141 0x8D
  53.     //10000000  0x80 OS_GBPAK_GBCART_ON
  54.     //10001101  0x8d return zz
  55.     //00001101  0xd =
  56.    
  57.     //00000100  0x4 OS_GBPAK_RSTB_DETECTION (reset byquery)
  58.     //00001000  0x8 OS_GBPAK_RSTB_STATUS (reset by query)
  59.     //00000001  0x1 OS_GBPAK_POWER
  60.  
  61.     tmp = _set_gbRomBank(bankc);
  62.     if(tmp!=0)
  63.     return -1;
  64.  
  65.             for(unsigned long banko=addr; banko<=0xFFE0; banko+=0x20){ //bank offset
  66.                
  67.                 memset( rdata, 0xFF, 32 );
  68.                
  69.                
  70.                 if(_get_gbRomAddr(banko, rdata)==0){
  71.                    
  72.                     data_cache_hit_writeback_invalidate(rdata,32);
  73.                    
  74.                     //write to cartspace
  75.                     dma_write_s(rdata, 0xb2000000+sd_offset, 0x20); //upper 32mb
  76.                    
  77.                     //write to rdram
  78.                     //memcpy(rom_data+sd_offset,rdata,0x20);
  79.                     sd_offset+=0x20;
  80.                    
  81.                 }
  82.                 else{
  83.                     return -1;
  84.                 }
  85.                
  86.             }
  87.     }
  88.    
  89.     return 0;
  90. }
  91.  
  92.  
  93.  
  94. int copy_save_toGbRam(uint8_t *ram_data){
  95.  
  96.     if(gbcart.ram!=TRUE)
  97.     return -1;
  98.  
  99.     //mbc1 - mbc3
  100.     //ram in 8KByte blocks up to 32Kb
  101.  
  102.     //mbc2
  103.     //512x4 bits RAM
  104.  
  105.     //mbc5
  106.     //128KByte RAM
  107.  
  108.  
  109.     uint8_t rdata[32];
  110.  
  111.     unsigned long addr=0xE000;
  112.     unsigned long ram_offset=0x00;
  113.     int tmp=0x00;
  114.    
  115.     //copy rambanks to sdram
  116.     for(int bankc=0; bankc < gbcart.rambanks; bankc++){ //bank count
  117.  
  118.     //get power status 0=off 1=on
  119.     if(_get_gbPower()!=1)
  120.     return -4;
  121.  
  122.     //get access mode
  123.     int as=_get_gbAccessState();
  124.  
  125.     tmp = _set_gbRamBank(bankc);
  126.     if(tmp!=0)
  127.     return -1;
  128.  
  129.         int bank_width=0xFFE0;
  130.         if(gbcart.mapper == GB_MBC2)
  131.         bank_width=0xE1E0;
  132.  
  133.             for(unsigned long banko=addr; banko<=bank_width; banko+=0x20){ //bank offset
  134.  
  135.            
  136.                     memset( rdata, 0xFF, 32 );
  137.                     //write to cartspace
  138.                     data_cache_hit_writeback_invalidate(rdata,32);
  139.                     dma_read_s(rdata, 0xb2000000+ram_offset, 0x20); //upper 32mb
  140.                     data_cache_hit_writeback_invalidate(rdata,32);
  141.                 // 
  142.  
  143.                 if(_set_gbRamAddr(banko, rdata)==0){
  144.                    
  145.                     ram_offset+=0x20;
  146.                 }
  147.                 else{
  148.                     return -1;
  149.                 }
  150.             }
  151.     }
  152.  
  153.     return 0;
  154. }
  155.  
  156.  
  157.  
  158. int copy_gbRam_toRAM(uint8_t *ram_data){
  159.  
  160.     if(gbcart.ram!=TRUE)
  161.     return -1;
  162.  
  163.     //mbc1 - mbc3
  164.     //ram in 8KByte blocks up to 32Kb
  165.  
  166.     //mbc2
  167.     //512x4 bits RAM
  168.  
  169.     //mbc5
  170.     //128KByte RAM
  171.  
  172.     uint8_t rdata[32];
  173.  
  174.     unsigned long addr=0xE000;
  175.     unsigned long sd_offset=0x00;
  176.     int tmp=0x00;
  177.    
  178.     //copy rambanks to sdram
  179.     for(int bankc=0; bankc < gbcart.rambanks; bankc++){ //bank count
  180.  
  181.     //get power status 0=off 1=on
  182.     if(_get_gbPower()!=1)
  183.     return -4;
  184.  
  185.     //get access mode
  186.     int as=_get_gbAccessState();
  187.  
  188.     tmp = _set_gbRamBank(bankc);
  189.     if(tmp!=0)
  190.     return -1;
  191.  
  192.         int bank_width=0xFFE0;
  193.         if(gbcart.mapper == GB_MBC2)
  194.         bank_width=0xE1E0;
  195.  
  196.             for(unsigned long banko=addr; banko<=bank_width; banko+=0x20){ //bank offset
  197.                
  198.                 memset( rdata, 0xFF, 32 );
  199.  
  200.                 if(_get_gbRamAddr(banko, rdata)==0){
  201.                    
  202.                     data_cache_hit_writeback_invalidate(rdata,32);
  203.                     dma_write_s(rdata, 0xb2000000+sd_offset, 0x20); //upper 32mb
  204.                    
  205.                     //to rdram
  206.                     //memcpy(ram_data+sd_offset,rdata,0x20);
  207.                     sd_offset+=0x20;
  208.                 }
  209.                 else{
  210.                     return -1;
  211.                 }
  212.             }
  213.     }
  214.  
  215.     return 0;
  216. }
  217.  
  218.  
  219.  
  220. int _set_gbPower(int status){
  221.     //1=on 2=off
  222.    
  223.     if(status){
  224.         //set on
  225.         status=0x84;
  226.     }else{
  227.         //set off
  228.         status=0xFE;
  229.     }
  230.    
  231.     int value=0;
  232.  
  233.         memset( data, status, 32 );
  234.         value = write_mempak_address( 0, 0x8001, data );
  235.        
  236.     return value;
  237. }
  238.    
  239.  
  240. //int get_gbPower(uint8_t *rdata){ 
  241. int _get_gbPower(void){
  242.  
  243.     uint8_t rdata[32];
  244.     memset( rdata, 0xFF, 32 );
  245.     int value=-1;
  246.  
  247.         value = read_mempak_address( 0, 0x8001, rdata );
  248.        
  249.     if(rdata[0]==0x00)
  250.     value=0;
  251.     else if(rdata[0]==0x84)
  252.     value=1;
  253.    
  254.     return value;
  255. }  
  256.    
  257.  
  258. //int get_gbAccessState(uint8_t *rdata){
  259. int _get_gbAccessState(void){
  260.  
  261.     uint8_t rdata[32];
  262.     memset( rdata, 0xFF, 32 );
  263.  
  264.     int value=0;
  265.  
  266.         value = read_mempak_address( 0, 0xB010, rdata );
  267.        
  268.     /* Sets bit 2 of the first return value if the access mode was recently changed.
  269.      * Will not set bit 2 again untill access mode is changed again.   
  270.      */
  271.  
  272.     if(rdata[0]==0x89) //mode 1
  273.     value=1;
  274.     else if(rdata[0]==0x80) //mode 0 //0x84 bot changed?
  275.     value=0;
  276.     else if(rdata[0]==0x84)
  277.     value=2;
  278.     else if(rdata[0]==0x40) //no gbcart inserted
  279.     value=3;
  280.     else
  281.     value=rdata[0];
  282.        
  283.     return value;
  284. }  
  285.    
  286.  
  287. int _set_gbAccessState(int status){
  288.  
  289.  
  290.    
  291.     if(status){
  292.         //mode 01
  293.         status=0x01;
  294.     }else{
  295.         //mode 00
  296.         status=0x00;
  297.     }
  298.    
  299.     int value=0;
  300.  
  301.         memset( data, status, 32 );
  302.         value = write_mempak_address( 0, 0xB010, data );
  303.        
  304.     return value;
  305. }
  306.  
  307.  
  308. int disable_gbRam(void){
  309.  
  310.     uint8_t sdata[32];
  311.     int value=0;
  312.    
  313.     if(gbcart.mapper==GB_NORM){
  314.         return -1; //no ram
  315.     }
  316.     else {
  317.         //same for all mbc 1-5 :>
  318.        
  319.         //protect ram again
  320.         memset(sdata, 0x00, 32);
  321.         value = write_mempak_address( 0, 0xA00C, sdata ); //prepare for ram enable
  322.         value = write_mempak_address( 0, 0xC000, sdata ); //set ram diable for reading/writing
  323.     }
  324.  
  325.  
  326. return 0;  
  327. }
  328.  
  329.  
  330. int _set_gbRamBank(int bank){
  331.  
  332.     if(gbcart.ram!=TRUE)
  333.     return -1;
  334.  
  335.     //e.g. 00
  336.     bank=0x01 * bank; // :D pointless
  337.     uint8_t sdata[32];
  338.     int value=0;
  339.    
  340.     if(gbcart.mapper==GB_NORM){
  341.         return -1; //no ram
  342.     }
  343.     else if( ((gbcart.mapper==GB_MBC1 || gbcart.mapper==GB_MBC3) && bank <=0x03)
  344.             || (gbcart.mapper==GB_MBC5 && bank <=0x0F) ){
  345.        
  346.         memset(sdata, 0x00, 32);
  347.         value = write_mempak_address( 0, 0xA00C, sdata ); //prepare for ram enable
  348.  
  349.         memset(sdata, 0x0A, 32); // 0x00 disable(rom) 0x0A enable(ram)
  350.         value = write_mempak_address( 0, 0xC000, sdata ); //set ram enable for reading/writing
  351.  
  352.         memset(sdata, 0x01, 32);
  353.         value = write_mempak_address( 0, 0xA00C, sdata ); //prepare for rambank switch
  354.  
  355.         memset(sdata, 0x01, 32); //00h rombanking 01h rambanking
  356.         value = write_mempak_address( 0, 0xE000, sdata ); //switch to rambanking
  357.        
  358.  
  359.         memset(sdata, bank, 32); //00h ram bank 00-03h or 00-0Fh
  360.         value = write_mempak_address( 0, 0xC000, sdata ); //set rambank 00h
  361.     }
  362.     else if(gbcart.mapper==GB_MBC2){
  363.         //512x4bits RAM, built-in into the MBC2 chip
  364.         //only one bank?
  365.        
  366.         memset(sdata, 0x00, 32);
  367.         value = write_mempak_address( 0, 0xA00C, sdata ); //prepare for ram enable
  368.  
  369.         memset(sdata, 0x01, 32); // enable/disable with whatever as value in the correct range
  370.         value = write_mempak_address( 0, 0xC000, sdata ); //set ram enable for reading/writing
  371.     }
  372.     else{
  373.         //mapper not found or out of range
  374.         return -1;
  375.     }
  376.    
  377.    
  378. return 0;
  379. }
  380.  
  381.  
  382. int _set_gbRomBank(int bank){
  383.  
  384.     //e.g. 00
  385.     bank=0x01 * bank; // :D pointless
  386.     uint8_t sdata[32];
  387.     int value=0;
  388.    
  389.     if(gbcart.mapper==GB_NORM || bank==0x00){
  390.        
  391.         memset( sdata, bank, 32 );
  392.         value = write_mempak_address( 0, 0xA00C, sdata );
  393.        
  394.     }
  395.     else if(gbcart.mapper==GB_MBC1){
  396.  
  397.        
  398.         if(bank==0x20 || bank==0x40 || bank==0x60) //bank 0x20, 0x40, 0x60 isn't addressable
  399.         return -1;
  400.                    
  401.         //NOTE: untested don't own a mbc1 cart with 32 banks or above ;_;
  402.         if(bank>0x20){ //don't need to set upper bits for every bank < 32
  403.            
  404.             //set to setting mode :>
  405.             memset( sdata, 0x01, 32);
  406.             value = write_mempak_address( 0, 0xA00C, sdata );
  407.             if(value!=0x00)
  408.             return value;
  409.            
  410.             //0x00 rombanking mode 0x01 rambanking mode
  411.             //disable ram
  412.             memset( sdata, 0x00, 32 );
  413.             value = write_mempak_address( 0, 0xE016, sdata ); //0x6000
  414.             if(value!=0x00)
  415.             return value;
  416.            
  417.             //set upper 2 bits (6,7)
  418.             //0h = +0 int
  419.             //1h = +32 int
  420.             //2h = +64 int
  421.             //3h = +96 int
  422.             if(bank>0x60){
  423.                 memset( sdata, 0x03, 32 );
  424.                 bank-=0x60;
  425.             }
  426.             else if(bank>0x40){
  427.                 memset( sdata, 0x02, 32 );
  428.                 bank-=0x40;
  429.             }
  430.             else{
  431.                 memset( sdata, 0x01, 32 ); 
  432.                 bank-=0x20;
  433.              }     
  434.            
  435.             //set bit 6 and 7
  436.             //8765 4321
  437.             //0XX0 0000
  438.             value = write_mempak_address( 0, 0xC000, sdata ); //write at 0x4000
  439.             if(value!=0x00)
  440.             return value;
  441.            
  442.             //TODO: disable high bits
  443.            
  444.         }
  445.        
  446.        
  447.         //lower bits
  448.         memset( sdata, 0x00, 32);
  449.         value = write_mempak_address( 0, 0xA00C, sdata );
  450.         if(value!=0x00)
  451.         return value;
  452.        
  453.         //set bit 1-5
  454.         //8765 4321
  455.         //000X XXXX
  456.         memset( sdata, bank, 32 );
  457.         value = write_mempak_address( 0, 0xE100, sdata );
  458.         if(value!=0x00)
  459.         return value;
  460.  
  461.         memset( sdata, 0x01, 32);
  462.         value = write_mempak_address( 0, 0xA00C, sdata );
  463.         if(value!=0x00)
  464.         return value;
  465.        
  466.     } //NOTE: untested don't own a mbc2 cart ;_;
  467.     else if(gbcart.mapper==GB_MBC2 && bank <=0x0F){
  468.        
  469.         memset( sdata, 0x00, 32);
  470.         value = write_mempak_address( 0, 0xA00C, sdata );
  471.         if(value!=0x00)
  472.         return value;
  473.        
  474.         //max 16 (0x00 - 0x0F) banks here
  475.         memset( sdata, bank, 32 );
  476.         value = write_mempak_address( 0, 0xE100, sdata );
  477.         if(value!=0x00)
  478.         return value;
  479.  
  480.         memset( sdata, 0x01, 32);
  481.         value = write_mempak_address( 0, 0xA00C, sdata );
  482.         if(value!=0x00)
  483.         return value;
  484.        
  485.     } //NOTE: untested don't own a mbc3 cart ;_;
  486.     else if(gbcart.mapper==GB_MBC3 && bank <=0x7F){
  487.  
  488.  
  489.         memset( sdata, 0x00, 32);
  490.         value = write_mempak_address( 0, 0xA00C, sdata );
  491.         if(value!=0x00)
  492.         return value;
  493.        
  494.         //whole 7 bit can be used for addressing here
  495.         //128 (0x00 - 0x7F) banks max
  496.         memset( sdata, bank, 32 );
  497.         value = write_mempak_address( 0, 0xE100, sdata );
  498.         if(value!=0x00)
  499.         return value;
  500.  
  501.         memset( sdata, 0x01, 32);
  502.         value = write_mempak_address( 0, 0xA00C, sdata );
  503.         if(value!=0x00)
  504.         return value;
  505.        
  506.     } //NOTE: untested don't own mbc5 cart ;_;
  507.     else if(gbcart.mapper==GB_MBC5){
  508.  
  509.         int bank5=bank; //preset < 0x100
  510.        
  511.         if(bank>0xFF){
  512.            
  513.             //set to setting mode :>
  514.             memset( sdata, 0x01, 32);
  515.             value = write_mempak_address( 0, 0xA00C, sdata );
  516.             if(value!=0x00)
  517.             return value;
  518.            
  519.             //0x00 rombanking mode 0x01 rambanking mode
  520.             //disable ram
  521.             memset( sdata, 0x00, 32 );
  522.             value = write_mempak_address( 0, 0xE016, sdata ); //0x6000
  523.             if(value!=0x00)
  524.             return value;
  525.            
  526.             //set bit 9 enable
  527.             //9 8765 4321
  528.             //X 0000 0000
  529.             memset( sdata, 0x01, 32 );
  530.             value = write_mempak_address( 0, 0xC000, sdata ); //write at 0x4000
  531.             if(value!=0x00)
  532.             return value;
  533.            
  534.             bank5=bank-0x100; //set for lower bits
  535.            
  536.         }
  537.        
  538.        
  539.         //lower bits
  540.         memset( sdata, 0x00, 32);
  541.         value = write_mempak_address( 0, 0xA00C, sdata );
  542.         if(value!=0x00)
  543.         return value;
  544.        
  545.         //set bit 1-8 even 0x00 if you like
  546.         //XXXX XXXX
  547.         memset( sdata, bank5, 32 );
  548.         value = write_mempak_address( 0, 0xE100, sdata );
  549.         if(value!=0x00)
  550.         return value;
  551.  
  552.         memset( sdata, 0x01, 32);
  553.         value = write_mempak_address( 0, 0xA00C, sdata );
  554.         if(value!=0x00)
  555.         return value;
  556.        
  557.         //TODO: disable high bit
  558.  
  559.     }
  560.    
  561.     gbcart.bank=bank;
  562.     return 0;
  563. }  
  564.  
  565. int _get_gbRamAddr(unsigned long addr, uint8_t *rdata){
  566.  
  567.     //mbc1,3,5 A000-BFFF
  568.     //mbc2 A000-A1FF
  569.     uint8_t sdata[32];
  570.     //addr e.g. 0xC138
  571.     int value=0;
  572.  
  573.     if((addr>=0xE000) && (addr<=0xFFFF)){
  574.    
  575.     memset(sdata, 0x02, 32);
  576.     value = write_mempak_address( 0, 0xA00C, sdata );//prepare for rambank read
  577.  
  578.     memset(rdata, 0x00, 32);
  579.     value = read_mempak_address( 0, addr, rdata );
  580.  
  581.     }
  582.     else
  583.         value=-1;
  584.        
  585.     return value;
  586. }  
  587.  
  588.  
  589. int _get_cpldEDGB(void){
  590.  
  591.     uint8_t sdata_[32];
  592.     uint8_t rdata_[32];
  593.     int value=0;
  594.  
  595.  
  596.  
  597.     int as=_get_gbAccessState();
  598.  
  599.     //int tmp = _set_gbRamBank(0);
  600.  
  601.  
  602.     memset(sdata_, 0x02, 32);
  603.     value = write_mempak_address( 0, 0xA00C, sdata_ ); //prepare for rambank read/write
  604.  
  605. //cmd_addr = 0xBF00 - reg_map_idx = 7
  606. //cmd_data = 0xBF80 - 8
  607.  
  608.  
  609.     //rom mask
  610.     memset(sdata_, 0x00, 32);
  611.     value = write_mempak_address( 0, 0xFF00, sdata_ ); //prepare for rambank read/write
  612.     memset(sdata_, 0xFF, 32); //28
  613.     value = write_mempak_address( 0, 0xFF80, sdata_ );
  614.  
  615.     //ram mask
  616.     memset(sdata_, 0x01, 32);
  617.     value = write_mempak_address( 0, 0xFF00, sdata_ ); //prepare for rambank read/write
  618.     memset(sdata_, 0xFF, 32); //04
  619.     value = write_mempak_address( 0, 0xFF80, sdata_ );  
  620.    
  621.    
  622.     //set mbc
  623.     memset(sdata_, 0x07, 32);
  624.     value = write_mempak_address( 0, 0xFF00, sdata_ ); //prepare for rambank read/write
  625.    
  626.     //set to 5 (+0x8)
  627.     memset(sdata_, 0x13, 32); // mbc5 0x5 or 0x8 - 13 -pokemon red mbc3 -> 11
  628.     value = write_mempak_address( 0, 0xFF80, sdata_ );
  629.    
  630. //int tks = _set_gbAccessState(0);
  631.    
  632.     //value = read_mempak_address( 0, 0xFF80, rdata_ );    
  633.     //value = rdata_[0];
  634.    
  635.     return value;
  636. }  
  637.  
  638.  
  639. int _set_gbRamAddr(unsigned long addr, uint8_t *sdata){
  640.  
  641.     //mbc1,3,5 A000-BFFF
  642.     //mbc2 A000-A1FF
  643.     uint8_t sdata_[32];
  644.  
  645.     //addr e.g. 0xC138
  646.     int value=0;
  647.  
  648.     if((addr>=0xE000) && (addr<=0xFFFF)){
  649.    
  650.     memset(sdata_, 0x02, 32);
  651.     value = write_mempak_address( 0, 0xA00C, sdata_ ); //prepare for rambank read/write
  652.  
  653.     value = write_mempak_address( 0, addr, sdata );
  654.  
  655.     }
  656.     else
  657.         value=-1;
  658.        
  659.     return value;
  660. }  
  661.  
  662.  
  663. int _get_gbRomAddr(unsigned long addr, uint8_t *rdata){
  664.  
  665.     //addr e.g. 0xC138
  666.     int value=0;
  667.  
  668.     if((addr>=0xC000) && (addr<=0xFFFF))
  669.         value = read_mempak_address( 0, addr, rdata );
  670.     else
  671.         value=-1;
  672.        
  673.     return value;
  674. }  
  675.  
  676.  
  677. int init_gbpak(void){
  678.  
  679.     memset( data, 0, 32 );
  680.  
  681.     if(_set_gbPower(0)!=0)
  682.     return -1;
  683.    
  684.     //get power status 0=off 1=on
  685.     if(_get_gbPower()!=0)
  686.     return -2;
  687.    
  688.     //set power off 0=off 1=on
  689.     if(_set_gbPower(1)!=0)
  690.     return -3;
  691.  
  692.     //get power status 0=off 1=on
  693.     if(_get_gbPower()!=1)
  694.     return -4;
  695.  
  696.     //double check is inserted is on?
  697.    
  698.     //get access mode
  699.     if(_get_gbAccessState()==-1)
  700.     return -5;
  701.  
  702.     //set mode 1
  703.     if(_set_gbAccessState(1)!=0)
  704.     return -6; 
  705.    
  706.  
  707. //  gbcart.cpld = _get_cpldEDGB();
  708.  
  709.  
  710.     //set bank 0
  711.     if(_set_gbRomBank(0x00)!=0)
  712.     return -7;     
  713.    
  714.     //get rdata
  715.     if(_get_gbRomAddr(0xC120, data)!=0) //header offset titel 0134
  716.     return -8;     
  717.  
  718.     //current bank
  719.     gbcart.bank=0;
  720.  
  721.     for( int i = 20; i < 31; i++ ) //20=0x14 -> 0x120+0x14 only 11 from 16 chars are safe
  722.     {
  723.         if(data[i]!=0)
  724.         gbcart.title[i-20]=data[i];
  725.         else
  726.         gbcart.title[i-20]=0x20;
  727.     }
  728.  
  729.     //get rdata
  730.     if(_get_gbRomAddr(0xC140, data)!=0) //header offset cart type
  731.     return -9; 
  732.    
  733.     gbcart.sgb = data[6]; //0x146 super gameboy functions 0x00=no 03=yes
  734.     gbcart._romsize = data[8];
  735.     gbcart._ramsize = data[9];
  736.  
  737.  
  738.     /*
  739.      00h -  32KByte (no ROM banking) - but small switching circuit ^^ 16KByte Banks!
  740.      01h -  64KByte (4 banks)
  741.      02h - 128KByte (8 banks)
  742.      03h - 256KByte (16 banks)
  743.      04h - 512KByte (32 banks)
  744.      05h -   1MByte (64 banks)  - only 63 banks used by MBC1
  745.      06h -   2MByte (128 banks) - only 125 banks used by MBC1 - 2048000=125*16*1024
  746.      07h -   4MByte (256 banks)
  747.      52h - 1.1MByte (72 banks)
  748.      53h - 1.2MByte (80 banks)
  749.      54h - 1.5MByte (96 banks) 1572864
  750.      */
  751.      
  752.      
  753.     switch (gbcart._romsize) {
  754.         case 0x00:  gbcart.rombanks=2;      break;
  755.         case 0x01:  gbcart.rombanks=4;      break;     
  756.         case 0x02:  gbcart.rombanks=8;      break; 
  757.         case 0x03:  gbcart.rombanks=16;     break; 
  758.         case 0x04:  gbcart.rombanks=32;     break; 
  759.         case 0x05:  gbcart.rombanks=64;     break; 
  760.         case 0x06:  gbcart.rombanks=128;    break; 
  761.         case 0x07:  gbcart.rombanks=256;    break; 
  762.         case 0x52:  gbcart.rombanks=72;     break; 
  763.         case 0x53:  gbcart.rombanks=80;     break; 
  764.         case 0x54:  gbcart.rombanks=96;     break; 
  765.         default:    gbcart.rombanks=2;      break;     
  766.     }
  767.    
  768.     //set romsize;
  769.     gbcart.romsize=gbcart.rombanks*BANKSIZE;
  770.    
  771.    
  772.     // 00h - None
  773.     // 01h - 2 KBytes
  774.     // 02h - 8 Kbytes
  775.     // 03h - 32 KBytes (4 banks of 8KBytes each)
  776.    
  777.     switch (gbcart._ramsize) {
  778.     case 0x00:  gbcart.rambanks=0;
  779.                 gbcart.ramsize=0;
  780.                 break;     
  781.     case 0x01:  gbcart.rambanks=1;
  782.                 gbcart.ramsize=2*1024;
  783.                 break; 
  784.     case 0x02:  gbcart.rambanks=1;
  785.                 gbcart.ramsize=8*1024;
  786.                 break; 
  787.     case 0x03:  gbcart.rambanks=4;
  788.                 gbcart.ramsize=4*8*1024;
  789.                 break; 
  790.     default:    gbcart.rambanks=0;
  791.                 gbcart.ramsize=0;  
  792.     }
  793.    
  794.  
  795.     //0x147 cartridge type
  796.     switch (data[7]) {
  797.     case 0x00:
  798.         gbcart.mapper = GB_NORM;
  799.         gbcart.ram = FALSE;
  800.         gbcart.battery = FALSE;
  801.         gbcart.rtc = FALSE;
  802.         gbcart.rumble = FALSE;
  803.         break;
  804.     case 0x01:
  805.         gbcart.mapper = GB_MBC1;
  806.         gbcart.ram = FALSE;
  807.         gbcart.battery = FALSE;
  808.         gbcart.rtc = FALSE;
  809.         gbcart.rumble = FALSE;
  810.         break;
  811.     case 0x02:
  812.         gbcart.mapper = GB_MBC1;
  813.         gbcart.ram = TRUE;
  814.         gbcart.battery = FALSE;
  815.         gbcart.rtc = FALSE;
  816.         gbcart.rumble = FALSE;
  817.         break;
  818.     case 0x03:
  819.         gbcart.mapper = GB_MBC1;
  820.         gbcart.ram = TRUE;
  821.         gbcart.battery = TRUE;
  822.         gbcart.rtc = FALSE;
  823.         gbcart.rumble = FALSE;
  824.         break;
  825.     case 0x05:
  826.         gbcart.mapper = GB_MBC2;
  827.         gbcart.ram = FALSE;
  828.         gbcart.battery = FALSE;
  829.         gbcart.rtc = FALSE;
  830.         gbcart.rumble = FALSE;
  831.         break;
  832.     case 0x06:
  833.         gbcart.mapper = GB_MBC2;
  834.         gbcart.ram = FALSE;
  835.         gbcart.battery = TRUE;
  836.         gbcart.rtc = FALSE;
  837.         gbcart.rumble = FALSE;
  838.         break;
  839.     case 0x08:
  840.         gbcart.mapper = GB_NORM;
  841.         gbcart.ram = TRUE;
  842.         gbcart.battery = FALSE;
  843.         gbcart.rtc = FALSE;
  844.         gbcart.rumble = FALSE;
  845.         break;
  846.     case 0x09:
  847.         gbcart.mapper = GB_NORM;
  848.         gbcart.ram = TRUE;
  849.         gbcart.battery = TRUE;
  850.         gbcart.rtc = FALSE;
  851.         gbcart.rumble = FALSE;
  852.         break;
  853.     case 0x0B:
  854.         gbcart.mapper = GB_MMMO1;
  855.         gbcart.ram = FALSE;
  856.         gbcart.battery = FALSE;
  857.         gbcart.rtc = FALSE;
  858.         gbcart.rumble = FALSE;
  859.         break;
  860.     case 0x0C:
  861.         gbcart.mapper = GB_MMMO1;
  862.         gbcart.ram = TRUE;
  863.         gbcart.battery = FALSE;
  864.         gbcart.rtc = FALSE;
  865.         gbcart.rumble = FALSE;
  866.         break;
  867.     case 0x0D:
  868.         gbcart.mapper = GB_MMMO1;
  869.         gbcart.ram = TRUE;
  870.         gbcart.battery = TRUE;
  871.         gbcart.rtc = FALSE;
  872.         gbcart.rumble = FALSE;
  873.         break;
  874.     case 0x0F:
  875.         gbcart.mapper = GB_MBC3;
  876.         gbcart.ram = FALSE;
  877.         gbcart.battery = TRUE;
  878.         gbcart.rtc = TRUE;
  879.         gbcart.rumble = FALSE;
  880.         break;
  881.     case 0x10:
  882.         gbcart.mapper = GB_MBC3;
  883.         gbcart.ram = TRUE;
  884.         gbcart.battery = TRUE;
  885.         gbcart.rtc = TRUE;
  886.         gbcart.rumble = FALSE;
  887.         break;
  888.     case 0x11:
  889.         gbcart.mapper = GB_MBC3;
  890.         gbcart.ram = FALSE;
  891.         gbcart.battery = FALSE;
  892.         gbcart.rtc = FALSE;
  893.         gbcart.rumble = FALSE;
  894.         break;
  895.     case 0x12:
  896.         gbcart.mapper = GB_MBC3;
  897.         gbcart.ram = TRUE;
  898.         gbcart.battery = TRUE;
  899.         gbcart.rtc = FALSE;
  900.         gbcart.rumble = FALSE;
  901.         break;
  902.     case 0x13:
  903.         gbcart.mapper = GB_MBC3;
  904.         gbcart.ram = TRUE;
  905.         gbcart.battery = TRUE;
  906.         gbcart.rtc = FALSE;
  907.         gbcart.rumble = FALSE;
  908.         break;
  909.     case 0x19:
  910.         gbcart.mapper = GB_MBC5;
  911.         gbcart.ram = FALSE;
  912.         gbcart.battery = FALSE;
  913.         gbcart.rtc = FALSE;
  914.         gbcart.rumble = FALSE;
  915.         break;
  916.     case 0x1A:
  917.         gbcart.mapper = GB_MBC5;
  918.         gbcart.ram = TRUE;
  919.         gbcart.battery = FALSE;
  920.         gbcart.rtc = FALSE;
  921.         gbcart.rumble = FALSE;
  922.         break;
  923.     case 0x1B:
  924.         gbcart.mapper = GB_MBC5;
  925.         gbcart.ram = TRUE;
  926.         gbcart.battery = TRUE;
  927.         gbcart.rtc = FALSE;
  928.         gbcart.rumble = FALSE;
  929.         break;
  930.     case 0x1C:
  931.         gbcart.mapper = GB_MBC5;
  932.         gbcart.ram = FALSE;
  933.         gbcart.battery = FALSE;
  934.         gbcart.rtc = FALSE;
  935.         gbcart.rumble = TRUE;
  936.         break;
  937.     case 0x1D:
  938.         gbcart.mapper = GB_MBC5;
  939.         gbcart.ram = TRUE;
  940.         gbcart.battery = FALSE;
  941.         gbcart.rtc = FALSE;
  942.         gbcart.rumble = TRUE;
  943.         break;
  944.     case 0x1E:
  945.         gbcart.mapper = GB_MBC5;
  946.         gbcart.ram = TRUE;
  947.         gbcart.battery = TRUE;
  948.         gbcart.rtc = FALSE;
  949.         gbcart.rumble = TRUE;
  950.         break;
  951.     default:
  952.         return FALSE;
  953.     }
  954.  
  955.  
  956.    
  957.    
  958.     return 0;
  959. }
Advertisement
Add Comment
Please, Sign In to add comment