home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / Flash.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-05-13  |  6.5 KB  |  248 lines

  1. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
  2. // Copyright (C) 1999-2003 Forgotten
  3. // Copyright (C) 2004 Forgotten and the VBA development team
  4.  
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2, or(at your option)
  8. // any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software Foundation,
  17. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18.  
  19. #include <stdio.h>
  20. #include <memory.h>
  21. #include "GBA.h"
  22. #include "Globals.h"
  23. #include "Flash.h"
  24. #include "Sram.h"
  25. #include "Util.h"
  26.  
  27. #define FLASH_READ_ARRAY         0
  28. #define FLASH_CMD_1              1
  29. #define FLASH_CMD_2              2
  30. #define FLASH_AUTOSELECT         3
  31. #define FLASH_CMD_3              4
  32. #define FLASH_CMD_4              5
  33. #define FLASH_CMD_5              6
  34. #define FLASH_ERASE_COMPLETE     7
  35. #define FLASH_PROGRAM            8
  36. #define FLASH_SETBANK            9
  37.  
  38. u8 flashSaveMemory[0x20000];
  39. int flashState = FLASH_READ_ARRAY;
  40. int flashReadState = FLASH_READ_ARRAY;
  41. int flashSize = 0x10000;
  42. int flashDeviceID = 0x1b;
  43. int flashManufacturerID = 0x32;
  44. int flashBank = 0;
  45.  
  46. static variable_desc flashSaveData[] = {
  47.   { &flashState, sizeof(int) },
  48.   { &flashReadState, sizeof(int) },
  49.   { &flashSaveMemory[0], 0x10000 },
  50.   { NULL, 0 }
  51. };
  52.  
  53. static variable_desc flashSaveData2[] = {
  54.   { &flashState, sizeof(int) },
  55.   { &flashReadState, sizeof(int) },
  56.   { &flashSize, sizeof(int) },  
  57.   { &flashSaveMemory[0], 0x20000 },
  58.   { NULL, 0 }
  59. };
  60.  
  61. static variable_desc flashSaveData3[] = {
  62.   { &flashState, sizeof(int) },
  63.   { &flashReadState, sizeof(int) },
  64.   { &flashSize, sizeof(int) },
  65.   { &flashBank, sizeof(int) },
  66.   { &flashSaveMemory[0], 0x20000 },
  67.   { NULL, 0 }
  68. };
  69.  
  70. void flashReset()
  71. {
  72.   flashState = FLASH_READ_ARRAY;
  73.   flashReadState = FLASH_READ_ARRAY;
  74.   flashBank = 0;
  75. }
  76.  
  77. void flashSaveGame(gzFile gzFile)
  78. {
  79.   utilWriteData(gzFile, flashSaveData3);
  80. }
  81.  
  82. void flashReadGame(gzFile gzFile, int version)
  83. {
  84.   if(version < SAVE_GAME_VERSION_5)
  85.     utilReadData(gzFile, flashSaveData);
  86.   else if(version < SAVE_GAME_VERSION_7) {
  87.     utilReadData(gzFile, flashSaveData2);
  88.     flashBank = 0;
  89.     flashSetSize(flashSize);
  90.   } else {
  91.     utilReadData(gzFile, flashSaveData3);
  92.   }
  93. }
  94.  
  95. void flashSetSize(int size)
  96. {
  97.   //  log("Setting flash size to %d\n", size);
  98.   flashSize = size;
  99.   if(size == 0x10000) {
  100.     flashDeviceID = 0x1b;
  101.     flashManufacturerID = 0x32;
  102.   } else {
  103.     flashDeviceID = 0x13; //0x09;
  104.     flashManufacturerID = 0x62; //0xc2;
  105.   }
  106. }
  107.  
  108. u8 flashRead(u32 address)
  109. {
  110.   //  log("Reading %08x from %08x\n", address, reg[15].I);
  111.   //  log("Current read state is %d\n", flashReadState);
  112.   address &= 0xFFFF;
  113.  
  114.   switch(flashReadState) {
  115.   case FLASH_READ_ARRAY:
  116.     return flashSaveMemory[(flashBank << 16) + address];
  117.   case FLASH_AUTOSELECT:
  118.     switch(address & 0xFF) {
  119.     case 0:
  120.       // manufacturer ID
  121.       return flashManufacturerID;
  122.     case 1:
  123.       // device ID
  124.       return flashDeviceID;
  125.     }
  126.     break;
  127.   case FLASH_ERASE_COMPLETE:
  128.     flashState = FLASH_READ_ARRAY;
  129.     flashReadState = FLASH_READ_ARRAY;
  130.     return 0xFF;
  131.   };
  132.   return 0;
  133. }
  134.  
  135. void flashSaveDecide(u32 address, u8 byte)
  136. {
  137.   //  log("Deciding save type %08x\n", address);
  138.   if(address == 0x0e005555) {
  139.     saveType = 2;
  140.     cpuSaveGameFunc = flashWrite;
  141.   } else {
  142.     saveType = 1;
  143.     cpuSaveGameFunc = sramWrite;
  144.   }
  145.  
  146.   (*cpuSaveGameFunc)(address, byte);
  147. }
  148.  
  149. void flashWrite(u32 address, u8 byte)
  150. {
  151.   //  log("Writing %02x at %08x\n", byte, address);
  152.   //  log("Current state is %d\n", flashState);
  153.   address &= 0xFFFF;
  154.   switch(flashState) {
  155.   case FLASH_READ_ARRAY:
  156.     if(address == 0x5555 && byte == 0xAA)
  157.       flashState = FLASH_CMD_1;
  158.     break;
  159.   case FLASH_CMD_1:
  160.     if(address == 0x2AAA && byte == 0x55)
  161.       flashState = FLASH_CMD_2;
  162.     else
  163.       flashState = FLASH_READ_ARRAY;
  164.     break;
  165.   case FLASH_CMD_2:
  166.     if(address == 0x5555) {
  167.       if(byte == 0x90) {
  168.         flashState = FLASH_AUTOSELECT;
  169.         flashReadState = FLASH_AUTOSELECT;
  170.       } else if(byte == 0x80) {
  171.         flashState = FLASH_CMD_3;
  172.       } else if(byte == 0xF0) {
  173.         flashState = FLASH_READ_ARRAY;
  174.         flashReadState = FLASH_READ_ARRAY;
  175.       } else if(byte == 0xA0) {
  176.         flashState = FLASH_PROGRAM;
  177.       } else if(byte == 0xB0 && flashSize == 0x20000) {
  178.         flashState = FLASH_SETBANK;
  179.       } else {
  180.         flashState = FLASH_READ_ARRAY;
  181.         flashReadState = FLASH_READ_ARRAY;
  182.       }
  183.     } else {
  184.       flashState = FLASH_READ_ARRAY;
  185.       flashReadState = FLASH_READ_ARRAY;
  186.     }
  187.     break;
  188.   case FLASH_CMD_3:
  189.     if(address == 0x5555 && byte == 0xAA) {
  190.       flashState = FLASH_CMD_4;
  191.     } else {
  192.       flashState = FLASH_READ_ARRAY;
  193.       flashReadState = FLASH_READ_ARRAY;
  194.     }
  195.     break;
  196.   case FLASH_CMD_4:
  197.     if(address == 0x2AAA && byte == 0x55) {
  198.       flashState = FLASH_CMD_5;
  199.     } else {
  200.       flashState = FLASH_READ_ARRAY;
  201.       flashReadState = FLASH_READ_ARRAY;
  202.     }
  203.     break;
  204.   case FLASH_CMD_5:
  205.     if(byte == 0x30) {
  206.       // SECTOR ERASE
  207.       memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)],
  208.              0,
  209.              0x1000);
  210.       systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
  211.       flashReadState = FLASH_ERASE_COMPLETE;
  212.     } else if(byte == 0x10) {
  213.       // CHIP ERASE
  214.       memset(flashSaveMemory, 0, flashSize);
  215.       systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
  216.       flashReadState = FLASH_ERASE_COMPLETE;
  217.     } else {
  218.       flashState = FLASH_READ_ARRAY;
  219.       flashReadState = FLASH_READ_ARRAY;
  220.     }
  221.     break;
  222.   case FLASH_AUTOSELECT:
  223.     if(byte == 0xF0) {
  224.       flashState = FLASH_READ_ARRAY;
  225.       flashReadState = FLASH_READ_ARRAY;
  226.     } else if(address == 0x5555 && byte == 0xAA)
  227.       flashState = FLASH_CMD_1;
  228.     else {
  229.       flashState = FLASH_READ_ARRAY;
  230.       flashReadState = FLASH_READ_ARRAY;
  231.     }
  232.     break;
  233.   case FLASH_PROGRAM:
  234.     flashSaveMemory[(flashBank<<16)+address] = byte;
  235.     systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
  236.     flashState = FLASH_READ_ARRAY;
  237.     flashReadState = FLASH_READ_ARRAY;
  238.     break;
  239.   case FLASH_SETBANK:
  240.     if(address == 0) {
  241.       flashBank = (byte & 1);
  242.     }
  243.     flashState = FLASH_READ_ARRAY;
  244.     flashReadState = FLASH_READ_ARRAY;
  245.     break;
  246.   }
  247. }
  248.