home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / EEprom.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-05-13  |  4.8 KB  |  192 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 "GBA.h"
  20. #include "EEprom.h"
  21. #include "Util.h"
  22.  
  23. extern int cpuDmaCount;
  24.  
  25. int eepromMode = EEPROM_IDLE;
  26. int eepromByte = 0;
  27. int eepromBits = 0;
  28. int eepromAddress = 0;
  29. u8 eepromData[0x2000];
  30. u8 eepromBuffer[16];
  31. bool eepromInUse = false;
  32. int eepromSize = 512;
  33.  
  34. variable_desc eepromSaveData[] = {
  35.   { &eepromMode, sizeof(int) },
  36.   { &eepromByte, sizeof(int) },
  37.   { &eepromBits , sizeof(int) },
  38.   { &eepromAddress , sizeof(int) },
  39.   { &eepromInUse, sizeof(bool) },
  40.   { &eepromData[0], 512 },
  41.   { &eepromBuffer[0], 16 },
  42.   { NULL, 0 }
  43. };
  44.  
  45. void eepromReset()
  46. {
  47.   eepromMode = EEPROM_IDLE;
  48.   eepromByte = 0;
  49.   eepromBits = 0;
  50.   eepromAddress = 0;
  51.   eepromInUse = false;
  52.   eepromSize = 512;
  53. }
  54.  
  55. void eepromSaveGame(gzFile gzFile)
  56. {
  57.   utilWriteData(gzFile, eepromSaveData);
  58.   utilWriteInt(gzFile, eepromSize);
  59.   utilGzWrite(gzFile, eepromData, 0x2000);
  60. }
  61.  
  62. void eepromReadGame(gzFile gzFile, int version)
  63. {
  64.   utilReadData(gzFile, eepromSaveData);
  65.   if(version >= SAVE_GAME_VERSION_3) {
  66.     eepromSize = utilReadInt(gzFile);
  67.     utilGzRead(gzFile, eepromData, 0x2000);
  68.   } else {
  69.     // prior to 0.7.1, only 4K EEPROM was supported
  70.     eepromSize = 512;
  71.   }
  72. }
  73.  
  74.  
  75. int eepromRead(u32 /* address */)
  76. {
  77.   switch(eepromMode) {
  78.   case EEPROM_IDLE:
  79.   case EEPROM_READADDRESS:
  80.   case EEPROM_WRITEDATA:
  81.     return 1;
  82.   case EEPROM_READDATA:
  83.     {
  84.       eepromBits++;
  85.       if(eepromBits == 4) {
  86.         eepromMode = EEPROM_READDATA2;
  87.         eepromBits = 0;
  88.         eepromByte = 0;
  89.       }
  90.       return 0;
  91.     }
  92.   case EEPROM_READDATA2:
  93.     {
  94.       int data = 0;
  95.       int address = eepromAddress << 3;
  96.       int mask = 1 << (7 - (eepromBits & 7));
  97.       data = (eepromData[address+eepromByte] & mask) ? 1 : 0;
  98.       eepromBits++;
  99.       if((eepromBits & 7) == 0)
  100.         eepromByte++;
  101.       if(eepromBits == 0x40)
  102.         eepromMode = EEPROM_IDLE;
  103.       return data;
  104.     }
  105.   default:
  106.       return 0;
  107.   }
  108.   return 1;
  109. }
  110.  
  111. void eepromWrite(u32 /* address */, u8 value)
  112. {
  113.   if(cpuDmaCount == 0)
  114.     return;
  115.   int bit = value & 1;
  116.   switch(eepromMode) {
  117.   case EEPROM_IDLE:
  118.     eepromByte = 0;
  119.     eepromBits = 1;
  120.     eepromBuffer[eepromByte] = bit;
  121.     eepromMode = EEPROM_READADDRESS;
  122.     break;
  123.   case EEPROM_READADDRESS:
  124.     eepromBuffer[eepromByte] <<= 1;
  125.     eepromBuffer[eepromByte] |= bit;
  126.     eepromBits++;
  127.     if((eepromBits & 7) == 0) {
  128.       eepromByte++;
  129.     }
  130.     if(cpuDmaCount == 0x11 || cpuDmaCount == 0x51) {
  131.       if(eepromBits == 0x11) {
  132.         eepromInUse = true;
  133.         eepromSize = 0x2000;
  134.         eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) |
  135.           ((eepromBuffer[1] & 0xFF));
  136.         if(!(eepromBuffer[0] & 0x40)) {
  137.           eepromBuffer[0] = bit;          
  138.           eepromBits = 1;
  139.           eepromByte = 0;
  140.           eepromMode = EEPROM_WRITEDATA;
  141.         } else {
  142.           eepromMode = EEPROM_READDATA;
  143.           eepromByte = 0;
  144.           eepromBits = 0;
  145.         }
  146.       }
  147.     } else {
  148.       if(eepromBits == 9) {
  149.         eepromInUse = true;
  150.         eepromAddress = (eepromBuffer[0] & 0x3F);
  151.         if(!(eepromBuffer[0] & 0x40)) {
  152.           eepromBuffer[0] = bit;
  153.           eepromBits = 1;
  154.           eepromByte = 0;         
  155.           eepromMode = EEPROM_WRITEDATA;
  156.         } else {
  157.           eepromMode = EEPROM_READDATA;
  158.           eepromByte = 0;
  159.           eepromBits = 0;
  160.         }
  161.       }
  162.     }
  163.     break;
  164.   case EEPROM_READDATA:
  165.   case EEPROM_READDATA2:
  166.     // should we reset here?
  167.     eepromMode = EEPROM_IDLE;
  168.     break;
  169.   case EEPROM_WRITEDATA:
  170.     eepromBuffer[eepromByte] <<= 1;
  171.     eepromBuffer[eepromByte] |= bit;
  172.     eepromBits++;
  173.     if((eepromBits & 7) == 0) {
  174.       eepromByte++;
  175.     }
  176.     if(eepromBits == 0x40) {
  177.       eepromInUse = true;
  178.       // write data;
  179.       for(int i = 0; i < 8; i++) {
  180.         eepromData[(eepromAddress << 3) + i] = eepromBuffer[i];
  181.       }
  182.       systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
  183.     } else if(eepromBits == 0x41) {
  184.       eepromMode = EEPROM_IDLE;
  185.       eepromByte = 0;
  186.       eepromBits = 0;
  187.     }
  188.     break;
  189.   }
  190. }
  191.   
  192.