gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > dswifi: flushing sends, and hangs

#166386 - zigg - Sat Feb 07, 2009 6:05 am

I'm working on a DS-based server that will allow a PC to read and write arbitrary sections of a game card's save chip. I figure this will be useful to easily write software that does the same thing that my old Band Brothers Save Tool did, without rewriting the entire chip each time and hopefully a bit easier on the whole.

Be kind with the following--I don't do C all that often, and I only know a few real basic things about DS architecture. :)

I'm compiling against r24 and dswifi 0.3.6. Here's today's code: http://www.zigg.com/tmp/savehost-20090206.tar.gz

Anyway, I've run into two problems today:

1. I seem to need some voodoo to get send() to actually send everything out.

Code:
        for(buf_p = buf; (buf_p - buf) < size; buf_p += SAVEHOST_BLOCK_SIZE) {
                iprintf("\n\x1b[1Asending: %u:%u ", (buf_p - buf), min(size - (buf_p - buf), SAVEHOST_BLOCK_SIZE));
                send(sock, buf_p, min(size - (buf_p - buf), SAVEHOST_BLOCK_SIZE), 0);
                /* seems to work for savsender, maybe useful here too? */
                swiWaitForVBlank();
                swiWaitForVBlank();
        }


The voodoo in question is the swiWaitForVBlank calls. Basically, I've lifted this pattern from savsender. If I don't add those calls, my dumped save ends up dropping bytes. (BTW, SAVEHOST_BLOCK_SIZE is currently 256, something else I lifted from savsender. I don't know how efficient that is, to be honest.)

Is there a better way to solve this problem?

2. The enclosed card.c is enhanced to support the 64Mbit save chip from Band Brothers DX--though I can't quite verify that it works 100% yet because I haven't successfully dumped more than about 480KBytes of the 8MBytes--my app hangs around that time each time I try. (I'm using the enclosed client/savedump.py, which just needs an IP address and will dump the save data to stdout. I did it with my old 256KByte Band Brothers save and it worked perfectly.)

Is there something I'm doing wrong? I guess I'm sort of asking someone to read all my code there, but I really have no idea where to start.

Thanks much for any help.[/code]

#166390 - Pete_Lockwood - Sat Feb 07, 2009 9:14 am

Without reading your code, and referring only to the snippet.. You're assuming that the send() call always succeeds in sending SAVEHOST_BLOCK_SIZE bytes.

The solution may be as simple as collecting the result of the send() and incrementing your pointer position by that value rather than always by SAVEHOST_BLOCK_SIZE. You might wanna try that and post back if it doesn't help.
_________________
It's not an illusion, it just looks like one.

#166411 - zigg - Sat Feb 07, 2009 4:10 pm

Oops! Yeah, that could explain a lot there. Clearly it has been far too long since I was in college taking networking. ;)

Followup question: is there a point to calling swiWaitForVBlank() in my loop at all, if I instead make sure that I'm sending until I can send no more?

#166412 - Maxxie - Sat Feb 07, 2009 4:30 pm

If you are failing to send more, it could be usefull to do a vblank wait to safe cpu power in descrete intervals instead of trying continously until it works.
_________________
Trying to bring more detail into understanding the wireless hardware

#166415 - Pete_Lockwood - Sat Feb 07, 2009 5:16 pm

zigg wrote:
Followup question: is there a point to calling swiWaitForVBlank() in my loop at all, if I instead make sure that I'm sending until I can send no more?


The perfect answer to that could be more DS-specific than I'm able to provide but I think personally I'd probably wait for a vblank if send() didn't send as many bytes as I asked it to send.

So something like

Code:

if(sent = send(x,y,z,size) != size)
    swiWaitForVBlank();


I think that's what Maxxie's suggesting too.
_________________
It's not an illusion, it just looks like one.

#166418 - zigg - Sat Feb 07, 2009 5:51 pm

Watching the send() return seems to have done it. I did still get one random hang but my success rate has gone way up.

vblank wait seems to be useful for performance, too; if I put enough in, I can send larger and larger blocks in a single send(). (Might be interesting to develop an algorithm to increase the number of waits depending on how well the sends are performing.)

Thanks for your help, all!

EDIT: Just saw your reply, Pete. I was replying to the thread that was sitting a little too long here in this tab instead of reloading. I didn't ignore your post :)