|
|
Please post all non-HAM GBA development topics here
by dagamer34 on Sun Feb 22, 2004 1:00 am
Does anybody know how to save to EEPROM without HAM code (even if it was supported once)?
I don't need to use all 256 kb of SRAM and EEPROM is just perfect for what I need to use.
I have tried to code what the no$gba tech reference says but I don't get a thing saved. VBA doesn't even create a save file for it.
Any help here? Some code snippets would help. Working EEPROM code would be even better!!!
while (your_engine >= my_engine)
my_engine++; 
-

dagamer34
- Expert

-
- Posts: 143
- Joined: Tue Oct 07, 2003 11:00 pm
- Location: Dallas, Tx
-
by Peter on Sun Feb 22, 2004 1:22 am
Hi,
staringmonkey released his saving routines on gbadev.org, it's in the source | gba section.
Title of it is Sm's Library v6
Hope it helps
-

Peter
- Professional

-
- Posts: 1281
- Joined: Thu Jan 30, 2003 12:00 am
- Location: Germany
-
by dagamer34 on Mon Feb 23, 2004 1:21 am
I'm sorry Peter, but I already have SRAM saving routines. What I need is EEPROM saving routines. Here is what I have so far:
- Code: Select all
// Initializes EEPROM for reading and writing (sets up wait states) void EEPROMInit (void) { // Clear bits 8, 9, 10 REG_WAITCNT &= ~(7 << 8); // Set bits 8 and 9 REG_WAITCNT |= 3 << 8; }
// Writes a block of 8 bytes to EEPROM s16 EEPROMwriteData (u32 size, u32 offset, u8 data[8]) { // EEPROM pointer volatile u8* EEPROMpointer = EEPROM; // Packet to transfer u8 packet[12]; // Starting offset for the data u32 start; // Loop counter u32 c; if (size != EEPROM_SIZE_4KB && size != EEPROM_SIZE_64KB) return -1; // Check that the EEPROM is good to go if (!(*EEPROMpointer & 1)) return -1; // Write the address into the packet if (size == EEPROM_SIZE_4KB) { if (offset <= 0 || offset > 64) return -1; packet [0] = 2 | (offset << 2); start = 1; } else { if (offset <= 0 || offset > 1024) return -1; packet [0] = 2 | (offset << 2); packet [1] = offset >> 6; start = 2; }
// Store the end-of-transfer indicator packet [start + 8] = 0; // Copy the data over for (c = 0; c < 8; c ++) packet [start + c] = data [c];
// Make the DMA transfer REG_DMA3SAD = (u32) &packet [0]; /* Starting address. */ REG_DMA3DAD = (u32) EEPROMpointer; /* Destination address. */ REG_DMA3CNT_L = (start + 8 + 2) / 2; /* Number of 16-bit words to transfer, either 5 or 6. */ REG_DMA3CNT_H = 1 << 15; /* Control bits and fire the DMA. */ REG_DISPCNT = REG_DISPCNT; /* Waste some clock cycles. */ while (REG_DMA3CNT_H & (1 << 15)); /* Wait out the transfer. */
/* Now wait until the EEPROM is back to ready. * Each cycle here must take at least one clock cycle. */ for (c = 0; c < 150000; c ++) if (*EEPROMpointer & 1) return 1; return 0; }
// Reads a block of 8 bytes from EEPROM s16 EEPROMreadData (u32 size, u32 offset, u8* data) { // EEPROM pointer volatile u8* EEPROMpointer = EEPROM; // Transfer packet to and from u8 packet [10]; // Size of the send packet in 16-bit words u32 packetSize; u32 c;
if (size != EEPROM_SIZE_4KB && size != EEPROM_SIZE_64KB) return -1;
// Check that the EEPROM is good to go if (!(*EEPROMpointer & 1)) return -1;
// Write the address into the packet if (size == EEPROM_SIZE_4KB) { if (offset <= 0 || offset > 64) return -1; packet [0] = 3 | (offset << 2); packet [1] = 0; packetSize = 1; } else { if (offset <= 0 || offset > 1024) return -1; packet [0] = 3 | (offset << 2); packet [1] = offset >> 6; packet [2] = 0; packetSize = 2; }
// Send the packet through DMA REG_DMA3SAD = (u32) &packet [0]; /* Starting address. */ REG_DMA3DAD = (u32) EEPROMpointer; /* Destination address. */ REG_DMA3CNT_L = packetSize; /* Number of 16-bit words to transfer. */ REG_DMA3CNT_H = 1 << 15; /* Control bits and fire the DMA. */ REG_DISPCNT = REG_DISPCNT; /* Waste some clock cycles. */ while (REG_DMA3CNT_H & (1 << 15)); /* Wait out the transfer. */
// Get the return packet REG_DMA3SAD = (u32) EEPROMpointer; /* Starting address. */ REG_DMA3DAD = (u32) &packet [0]; /* Destination address. */ REG_DMA3CNT_L = 5; /* Number of 16-bit words to transfer. */ REG_DMA3CNT_H = 1 << 15; /* Control bits and fire the DMA. */ REG_DISPCNT = REG_DISPCNT; /* Waste some clock cycles. */ while (REG_DMA3CNT_H & (1 << 15)); /* Wait out the transfer. */
// Unpack the return packet for (c = 0; c < 8; c ++) data [c] = (packet [c] >> 4) | (packet [c + 1] << 4);
return 0; /* Woot. */ }
I know its a lot, but please try to actually look at the code. Maybe emanuel can help me. I think he had some working routines...
while (your_engine >= my_engine)
my_engine++; 
-

dagamer34
- Expert

-
- Posts: 143
- Joined: Tue Oct 07, 2003 11:00 pm
- Location: Dallas, Tx
-
by dagamer34 on Sun May 02, 2004 4:50 am
I was looking around and I saw this post on gbadev.org. Here's the working code so far, but it only works in VBA, not hardware. Can anyone figure out what is wrong?
DrawText is simple a function to display data to the screen, but that isn't the problem. Neither are the key polling functions because I flashed a .sav file to my cart but came up with nothing. This code was tested on a EZFA.
- Code: Select all
#define EEPROM_ADDRESS (volatile u16*)0xD000000 #define REG_EEPROM (*(volatile u16*)0xD000000) #define REG_DM3SAD (*(volatile u32*)0x40000D4) #define REG_DM3DAD (*(volatile u32*)0x40000D8) #define REG_DM3CNT (*(volatile u32*)0x40000DC)
void EEPROM_SendPacket( u16* packet, int size ) { REG_DM3SAD = (u32)packet; REG_DM3DAD = (u32)EEPROM_ADDRESS; REG_DM3CNT = 0x80000000 + size; }
void EEPROM_ReceivePacket( u16* packet, int size ) { REG_DM3SAD = (u32)EEPROM_ADDRESS; REG_DM3DAD = (u32)packet; REG_DM3CNT = 0x80000000 + size; }
void EEPROM_Read( int offset, u8* dest ) // dest must point to 8 bytes { u16 packet[68]; u8* out_pos; u16* in_pos; u8 out_byte; int byte, bit;
// Read request packet[0] = 1; packet[1] = 1;
// 6 bits eeprom address (MSB first) packet[2] = offset>>5; packet[3] = offset>>4; packet[4] = offset>>3; packet[5] = offset>>2; packet[6] = offset>>1; packet[7] = offset;
// End of request packet[8] = 0;
// Do transfers EEPROM_SendPacket( packet, 9 ); EEPROM_ReceivePacket( packet, 68 );
// Extract data in_pos = &packet[4]; out_pos = dest; for( byte = 7; byte >= 0; --byte ) { out_byte = 0; for( bit = 7; bit >= 0; --bit ) { out_byte += (*in_pos++)<<bit; } *out_pos++ = out_byte; } }
void EEPROM_Write( int offset, u8* source ) // source must point to 8 bytes { u16 packet[73]; u8* in_pos; u16* out_pos; u8 in_byte; int byte, bit;
// Write request packet[0] = 1; packet[1] = 0;
// 6 bits eeprom address (MSB first) packet[2] = offset>>5; packet[3] = offset>>4; packet[4] = offset>>3; packet[5] = offset>>2; packet[6] = offset>>1; packet[7] = offset;
// Extract data in_pos = source; out_pos = &packet[8]; for( byte = 7; byte >= 0; --byte ) { in_byte = *in_pos++; for( bit = 7; bit >= 0; --bit ) { *out_pos++ = in_byte>>bit; } }
// End of request packet[72] = 0;
// Do transfers EEPROM_SendPacket( packet, 73 );
// Wait for EEPROM to finish (should timeout after 10 ms) while( (REG_EEPROM & 1) == 0 ); }
int main () { SetMode (MODE_0 | BG0_ENABLE); u8 buffer[8]; InitText (0, 0, 8); // Edited out some set up stuff here
// Set up waitstates for EEPROM access etc. *(volatile unsigned short *)0x04000204 = 0x4317;
do { EEPROM_Read( 0, buffer ); DrawText (0, 0, "%d\n", buffer[0] ); do { WaitVSync (); PollKeys (); } while (!KeyIsDown (KEY_A)); ++buffer[0]; DrawText (0, 1, "Read Successfull"); EEPROM_Write( 0, buffer ); DrawText (0, 2, "Write Successfull"); } while( 1 );
return 0; }
while (your_engine >= my_engine)
my_engine++; 
-

dagamer34
- Expert

-
- Posts: 143
- Joined: Tue Oct 07, 2003 11:00 pm
- Location: Dallas, Tx
-
by caitsith2 on Wed Jun 23, 2004 8:01 am
Been doing some tests on an actual cart, not a flash cart, but a cart with EEPROM built in, and your code seems to work nicely for reading/writing EEPROM.
What I found is that there seems to be a slight bug, in the reading code, unless it has to do with the EEPROM itself, where all the bytes read, will show up as being byte += 2 of the actual byte stored.
In testing of loading of a known SMA1 save, the writing itself worked perfectly.
I wonder if maybe we should be adding a string that the flash cart hardware would be looking for, like EEPROM_V120, to tell the flash cart that the save type is EEPROM, just as SRAM_V112 tells the flashcart that the save type is SRAM. I know a real cart with this save type does not care if the string is present, but for a flashcart, that may be all that makes a difference.
-

caitsith2
- Newbie

-
- Posts: 7
- Joined: Fri Aug 08, 2003 11:00 pm
by dagamer34 on Thu Jun 24, 2004 4:36 am
caitsith2 wrote:Been doing some tests on an actual cart, not a flash cart, but a cart with EEPROM built in, and your code seems to work nicely for reading/writing EEPROM.
What I found is that there seems to be a slight bug, in the reading code, unless it has to do with the EEPROM itself, where all the bytes read, will show up as being byte += 2 of the actual byte stored.
In testing of loading of a known SMA1 save, the writing itself worked perfectly.
I wonder if maybe we should be adding a string that the flash cart hardware would be looking for, like EEPROM_V120, to tell the flash cart that the save type is EEPROM, just as SRAM_V112 tells the flashcart that the save type is SRAM. I know a real cart with this save type does not care if the string is present, but for a flashcart, that may be all that makes a difference.
Yeah, and the code has worked on a couple of flash carts too, except for the one I own (EZFA). And it isn't really my code. I simply copied and pasted it from gbadev.org in case someone didn't catch it.
Most modern flash carts actually look for the save string to determine the size of the save file. I know the EZFA client does it, not sure about the others though...
By the way, I changed the code up above after you posted your reply. It doesn't work with the EZFA though(which sucks!) but other people say that it works on their flash carts.
while (your_engine >= my_engine)
my_engine++; 
-

dagamer34
- Expert

-
- Posts: 143
- Joined: Tue Oct 07, 2003 11:00 pm
- Location: Dallas, Tx
-
by zigg on Sat Jan 29, 2005 6:05 pm
I've been trying to get this code to work myself; I'm only interested in reading EEPROM.
On a real EEPROM cart, I get bytes that are the actual byte plus 1 or 2 (no pattern that I can detect...); in VBA I get the actual data.
Is there any better code out there?
-

zigg
- Newbie

-
- Posts: 1
- Joined: Sat Jan 29, 2005 12:00 am
Return to General GBA development
Users browsing this forum: No registered users and 2 guests
|