/********************************************************************/
/*         AgbEeprom.h                                              */
/*            4kbit EEPROM Library Header    ver. 1.2.4             */
/*                                                                  */
/*                                         last modified 2003.08.04 */
/*                                                                  */
/*         Copyright (C) 2000-2001 NINTENDO Co.,Ltd.                */
/********************************************************************/
#ifndef __AGB_EEPROM_H__
#define __AGB_EEPROM_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <Agb.h>

// define data----------------------------------
#define EEPROM_RETRY_MAX        3   // ProgramEepromDwordEx function maximum retry number

#define PHASE_VERIFY			0x0000	//Error Code
#define	PHASE_PROGRAM			0x0001
#define	PHASE_DEVICE_CHECK		0x0080
#define	PHASE_PARAMETER_CHECK	0x00ff

#define	RESULT_OK				0x0000
#define	RESULT_ERROR			0x8000
#define	RESULT_TIMEOUT			0x4000


typedef struct eepromTypeTag {
    u32     size;                   // Byte size
    u16     adrCount;               // Total number of addresses
    u16     agbWait;                // Read/write wait value of AGB game pak bus (ROM2 area)
                                    //  (Used inside the library)
    u8      adrBit;                 // Number of address bits at DMA transfer time
}eepromType;                        // (Used inside the library)

/*******************************************************************
 For 4K/64Kbit EEPROM, the device structure information is defined in the 
 above-mentioned eepromType structure inside the library in the format shown below. 
 These constants can be accessed by executing IdentifyEeprom and 
 then referencing the global variable [const eepromType *eeprom].



4Kbit EEPROM
{
    0x00000200,                     // Total byte size
    0x0040,                         // Total number of addresses
    CST_ROM2_1ST_8WAIT|CST_ROM2_2ND_8WAIT,  // 8/8 wait
    6,                              // Number of address bits at DMA transfer time 
};

64Kbit EEPROM
{
    0x00002000,                     // Total byte size
    0x0400,                         // Total number of addresses
    CST_ROM2_1ST_8WAIT|CST_ROM2_2ND_8WAIT,  // 8/8 wait
    14,                             // Number of address bits at DMA transfer time
};
*/
/*------------------------------------------------------------------*/
/*         Global variables                                         */
/*------------------------------------------------------------------*/
extern const eepromType *eeprom;    //  Pointer to the data that shows the 
                                    // structure of the EEPROM which is stored 
                                    // after IdentifyEeprom is executed. 

/*------------------------------------------------------------------*/
/*        Device identification and initial settings                */
/*------------------------------------------------------------------*/
extern u16 IdentifyEeprom(u16 eeprom_KbitSize);

/* This function determines which EEPROM is mounted in the Game Pak 
  based on the value specified by the argument eeprom_KbitSize, and sets
  the EEPROM size, total address count and access speed. (EEPROM does not
  have a device ID, so identification of which EEPROM is being used is 
  determined from the argument that is passed.)
  The obtained EEPROM data can be referenced using the global variable 
  eepromType *eeprom. (For details about eepromType see the definitions above.)
  This function is called once prior to accessing EEPROM (including prior
  to reading the device.)
  When an incorrect argument is passed, an error is returned and the data
  for 4Kbit EEPROM are set in "eepromType *eeprom".

  <Arguments>
   u16 eeprom_KbitSize : The size of EEPROM being used, in Kbits
  <Return values>
   u16 result   : 0 is normal end, non-zero is an argument error

   [Usage examples]
    When using 4Kbit EEPROM   IdentifyEeprom(4);
    When using 64Kbit EEPROM  IdentifyEeprom(64);
*/

/*------------------------------------------------------------------*/
/*           Read Double-Word (8 bytes) Data                        */
/*------------------------------------------------------------------*/

extern u16 ReadEepromDword(u16 epAdr,u16 *dst);

/*  Reads 8 bytes of data from the target EEPROM address and loads
    it starting from the address "dst." If outside range with target 
    EEPROM address, reports an error.
    *This routine uses DMA3. All interrupts are prohibited while DMA
    is being used inside the routine.
    <Arguments>
    u32 epAdr :Target EEPROM Address (4k:0x00-0x3f,64k:0x0000-0x03ff)
    u16 *dst  :Read Data transfer destination
    <Return Values>
    u16 result : 0 is a normal end, Not 0 is an error

    *Please note all that interrupts are prohibited during a certain period 
    (about 40-60 microseconds) when this function is called.  
    Refer to "Cautions when using EEPROM access function" in the 
    "AGB Back-up Library Manual" for details. 
    Do not use DMAs which start up automatically with specified timing 
    such as direct sound, V/H blank synchronization, display synchronization,
    or Game Pak request when this function is called. 

*/

/*------------------------------------------------------------------*/
/*           Double-Word (8 bytes) Write Data                       */
/*------------------------------------------------------------------*/

extern u16 ProgramEepromDword_NoWait( u16 epAdr, u16 *src);	
//For 64kEEPROM (4k not possible)
extern u16 ProgramEepromDword(u16 epAdr,u16 *src);	//For 4k and 64k EEPROM

/* Write 8 bytes of data from src address to target EEPROM address.
   If outside range with target EEPROM address, reports an error.

*This routine uses DMA3. All interrupts are prohibited while DMA is being 
 used inside the routine.


ProgramEepromDword requires about 10ms to write, but for 
ProgramEepromDword_NoWait, this amount of time may change due to individual 
device differences. The standard ranges from 2ms to 10ms. Be sure to program 
so that timimg errors do not occur. ProgramEepromDword_NoWait cannot be used 
by 4k EEPROM (an error will occur).

Because time measurement for the timeout decision is determined by the count 
of the VCOUNT register, if an interrupt process that requires more than one 
frame interval starts while processing this function, the time measurement 
will be thrown off. Please do not let the interrupts that need more than one 
frame interval occur during the process of this function.

   <Arguments>
   u32 epAdr :Target EEPROM Address (4k:0x00-0x3f,64k:0x0000-0x03ff)
   u16 *dst  :Write source data address
   <Return Values>
   u16 result : 0 is a normal end, Not 0 is an error

   *Please note that all interrupts are prohibited during a certain period 
   (about 40-60 microseconds) when this function is called.  
   Refer to "Cautions when EEPROM access function is used" in the 
   "AGB Back-up Library Manual" for details. 
   Do not use DMAs which start up automatically with specified timing 
   such as direct sound, V/H blank synchronization, display synchronization,
   or Game Pak request when this function is called. 
*/

/*------------------------------------------------------------------*/
/*            Verify Doubleword (8 bytes) Data                      */
/*------------------------------------------------------------------*/

extern u16 VerifyEepromDword(u16 epAdr,u16 *src);

/* Verify 8 bytes of data in target EEPROM address with data from 
   address "src".
   *This routine uses DMA 3. When DMA is being used in this routine,
   all interrupts are prohibited.
   <Arguments>
   u16 epAdr :Target EEPROM Address (4k:0x00-0x3f,64k:0x0000-0x03ff)
   u8 *src  :Verify source address
   <Return Values>
   u16   :0 is a normal end, Not 0 is an error

   *Please note that all interrupts are prohibited during a certain period 
   (about 40-60 microseconds) when this function is called.  
   Refer to "Cautions when Using EEPROM Access Functions" in the 
   "AGB Back-up Library Manual" for details. 
   Do not use DMAs which start up automatically with specified timing 
   such as direct sound, V/H blank synchronization, display synchronization,
   or Game Pak request when this function is called. 
*/

/*------------------------------------------------------------------*/
/*          Write & Verify data in double word (8byte)              */
/*------------------------------------------------------------------*/

extern u16 ProgramEepromDwordEx_NoWait(u16 epAdr,u16 *src);   //For 64kEEPROM (4k not possible)
extern u16 ProgramEepromDwordEx(u16 epAdr,u16 *src);		//For 4k and 64kEEPROM

  
/* After writing internally with ProgramEepromDword_NoWait, 
   ProgramEepromDwordEx_NoWait verifies with VerifyEepromDword, and if an 
   error occurs it will retry a maximum of EEPROM_RETRY_MAX (as defined by 
   AgbEeprom.h) number of times.  ProgramEepromDwordEx is identical to 
   ProgramEepromDwordEx_NoWait except for its internal use of 
   ProgramEepromDword.  Be sure to program so that timing errors do not 
   occur when using ProgramEepromDwordEx_NoWait.

    Refer to the explanations for ProgramEepromDword and 
    ProgramEepromDword_NoWait for more information.
    <Argument>
     u32 epAdr  :Target EEPROM address (4k:0x00-0x3f,64k:0x0000-0x03ff)
     u16 *dst   :Write source data address
    <Return value> 
     u16 result : 0 is a normal end. Not 0 is an error.

   *Be aware that all interrupts are prohibited for a certain period
   of time (about 40-60 microseconds) when this function is called. 
   Refer to "Cautions when using EEPROM access function" in the "AGB
   Backup Library Manual" for details. 
   Do not use DMAs which start up automatically with specified timing 
   such as direct sound, V/H blank synchronization, display synchronization,
   or Game Pak request when this function is called. 

*/

#ifdef __cplusplus
}   /* extern "C" */
#endif

#endif  // __AGB_EEPROM_H__
