#include <stdio.h>
#include <stdint.h>
#include "mem.h"
#include "gba.h"

unsigned char eeprom[65536*2];
int eepaddr,eepwr,eepstat,eeppos;

void initeeprom()
{
        FILE *f;
        memset(eeprom,0,65536*2);
/*        f=fopen("Sonic Advance 2 # GBA.sav","rb");
        fread(eeprom,65536,1,f);
        fclose(f);*/
}

void loadeeprom(char *fn)
{
        FILE *f;
        int c;
        printf("Loading %s\n",fn);
        f=fopen(fn,"rb");
        if (f)
        {
                fseek(f,-1,SEEK_END);
                c=ftell(f)+1;
                fseek(f,0,SEEK_SET);
                printf("Save len %i\n",c);
                savelen=c;
                fread(eeprom,65536*2,1,f);
                fclose(f);
        }
        else
        {
                memset(eeprom,0,65536*2);
                c=0;
        }
        savechange=0;
}

void saveeeprom(char *fn)
{
        FILE *f;
        if (!savechange) return;
        f=fopen(fn,"wb");
        if (f)
        {
                fwrite(eeprom,savelen,1,f);
                fclose(f);
        }
}

void scaneeprom()
{
        char str[]="EEPROM_V";
        int slen=strlen(str);
        int c,d;
        eeprompresent=0;
        for (c=0;c<((16*1024*1024)-slen);c++)
        {
                for (d=0;d<slen;d++)
                {
                        if (romb[c+d]!=str[d]) break;
                }
                if (d==slen)
                {
                        printf("Found EEPROM in cart\n");
                        eeprompresent=1;
                        savelen=512;
                        return;
                }
        }
}

void scanother()
{
        char strs[4][16]={"SRAM_V","FLASH_V","FLASH512_V","FLASH1M_V"};
        int slen[4];
        int c,d,e;
        srampresent=flashpresent=flashsize=0;
        for (c=0;c<4;c++) slen[c]=strlen(strs[c]);
        for (e=0;e<4;e++)
        {
                for (c=0;c<((16*1024*1024)-slen[e]);c++)
                {
                        for (d=0;d<slen[e];d++)
                        {
                                if (romb[c+d]!=strs[e][d]) break;
                        }
                        if (d==slen[e])
                        {
                                printf("Found %s in cart\n",strs[e]);
                                if (e==0)
                                {
                                        srampresent=1;
                                        savelen=65536;
                                }
                                else      flashpresent=1;
                                if (e==3)
                                {
                                        flashsize=1;
                                        savelen=131072;
                                }
                                else
                                {
                                        flashsize=0;
                                        savelen=65536;
                                }
                                return;
                        }
                }
        }
}

void writeeeprom(unsigned short val)
{
//        /*if (!eepstat) */printf("EEPROM %02X\n",dmasize);
//        printf("Write EEPROM   %i %i %i %i  %02X\n",eepstat,eeppos,eepwr,val&1,dmasize);
        val&=1;
        switch (eepstat)
        {
                case 0: eepstat++; break;
                case 1: eepwr=val; eepstat++; eepaddr=0; break;
                case 2: case 3: case 4: case 5: case 6: case 7:
                case 15: case 16: case 17: case 18:
                case 19: case 20: case 21: case 22:
                eepaddr=(eepaddr<<1)|val;
                eepstat++;
                eeppos=0;
                if (eepstat==8 && (dmasize==0x11 || dmasize==0x51)) eepstat=15;
                if (eepstat==23)
                {
                        eepstat=8;
                        savelen=8192;
                }
//                printf("EEPADDR %i %i\n",eepaddr,eeppos);
                break;
                case 8: if (eepwr) return;
//                printf("Change EEPROM!\n");
//                printf("%i\n",(eeppos>>3)+(eepaddr*8));
                eeprom[(eeppos>>3)+(eepaddr*8)]&=~(1<<(7-(eeppos&7)));
                if (val) eeprom[(eeppos>>3)+(eepaddr*8)]|=(1<<(7-(eeppos&7)));
                eeppos++;
                if (eeppos==64)
                   eepstat=13;
                savechange=1;
                break;
                case 13:
                if (eepwr) return;
                eepstat++;
                break;
        }
}

unsigned short readeeprom()
{
        int dat;
//        printf("Read EEPROM    %i %i %i ",eepstat,eeppos,eepwr);
        switch (eepstat)
        {
                case 8: case 9: case 10: case 11: /*printf("0\n");*/ eepstat++; return 0; /*4 junk bits*/
                case 12:
                if (!eepwr) return 0;
                dat=eeprom[(eeppos>>3)+(eepaddr*8)];
                dat&=(1<<(7-(eeppos&7)));
//                printf("%i\n",(dat)?1:0);
                eeppos++;
                if (eeppos==64)
                   eepstat=0;
//                printf("%i\n",(eeppos>>3)+(eepaddr*8));
                return (dat)?1:0;
                case 14:
                eepstat=0;
//                printf("1\n");
                return 1;
        }
}
