#71709 - linus - Tue Feb 14, 2006 2:08 am
Who is working on the SCSD fat driver, is it chishm or did cory1492 help out converting it to C. Does anyone know why its not working, when i tried it i couldnt get it to detect my SD card. I had a look at the code and it looked like it was doing the equivilent as before. What are the problems with it?
#71745 - chishm - Tue Feb 14, 2006 5:51 am
The one included in the official FAT lib is what I converted from the ASM code. I haven't got a SC, so I haven't been able to find out why it doesn't work. Play with it all you want, and if you get it working, I wanna here about it :)
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com
#71802 - linus - Tue Feb 14, 2006 5:05 pm
hi ho hi ho its off to work i go...
well im no expert but i dont even think its the asm functions you replaced. its not detecting my card (and the SCSD_Unlock, SCSD_IsInserted functions were in C).
Ive replaced those functions with the older ones and instead of disc_Init returning false it just doesnt return, but this is probably down to my crappy glueing in of the old code.
as i said im no expert im just trying to help out because you dont have a SC, but i was wondering surely
old code in SCSD_IsInserted:
return ((0x9800000 & 0x0300) == 0);
new code:
return (0x9800000 & 0x300);
do the opposite of each other. (ive replaced the defined names to their actual numbers)
#71818 - kevinc - Tue Feb 14, 2006 6:07 pm
Weird, last week I did a quick experiment with my SCSD and cory1492's drivers and did manage to get a directory listing.
#71833 - linus - Tue Feb 14, 2006 7:40 pm
ohhhh really, where is cory's work these days?
#71889 - chishm - Wed Feb 15, 2006 4:04 am
heh, I completely missed that error. That's just what happens when you don't have a device to test on.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com
#72332 - linus - Fri Feb 17, 2006 7:25 pm
I was wrong when is said this :
Quote: |
old code in SCSD_IsInserted:
return ((0x9800000 & 0x0300) == 0);
new code:
return (0x9800000 & 0x300); |
actually the new code was
return (0x9800000 == 0x300);
but anyway when i replace the old with the new it just doesnt return from disc_Init i havent been able to devote much time to this, but im still looking through every now and again.
Wheres corys code kev?
#72333 - kevinc - Fri Feb 17, 2006 7:38 pm
#72334 - linus - Fri Feb 17, 2006 7:43 pm
ah that code... i was just hoping you had something newer than that :) because im pretty sure dma didnt work with it yet, or there was some problem.
#72451 - cory1492 - Sat Feb 18, 2006 5:39 pm
#define sd_comadd (*(vu16*)(0x09800000))
if sd_comadd == 0x300 return 1
looks fine to me with my limited asm knowledge, I dont think card inserted is where the problem is... but here is some info that I just worked out anyway (and changed a bunch of times if you are reading this thread at the moment):
Code: |
#define SD_COMS (*(vu16*)(0x09800000))
_Unlock(); //does the unlock
u32 comstat = SD_COMS; |
SD_COMS always returns 0xFCFF or 0b1111110011111111 (whether I specify u16 or u32 for the variable)
Code: |
#define SD_COMS (*(vu32*)(0x09800000))
_Unlock(); //does the unlock
u32 comstat = SD_COMS; |
returns 0b11111100111111111111110011111111 (0xFCFFFCFF)
Code: |
.TEXT
.equ sd_comadd,0x9800000
.ALIGN
.GLOBAL com_test
.CODE 32
com_test:
ldr r1,=sd_comadd
ldrh r0,[r1]
bx r14
.END |
always returns 0xFCFF (havent figured out where/how that 0x300 comes into play in asm though, which is a big part of my confusion with producing a converted driver - why it is opposite to what this asm tells me:) Code: |
tst r1,#0x300
moveq r0,#1
movne r0,#0 |
- and for me at least,
always comes up as 0 (0xfcff & 0x300) seems to come up as zero when I printf it.
0000001100000000 anded with
1111110011111111
should be
0000000000000000
hence return (0x9800000 == 0xFCFF) should be sufficient
Code: |
#define SD_STS_INSERTED 0xFCFF |
seems to work great for the startup (it calls and returns fine from inside disk_Init)
- with this change it is failing at the first read sector (never returns, Im assuming becaus of the & 0x100 being the same problem as above)
also changing
Code: |
#define SD_STS_BUSY 0xFEFF
...
while (SD_DATARADD_16 == SD_STS_BUSY);
|
moves things a little farther, but freezes at the for loop just after the while in ReadSector, and then for some odd reason everything goes haywire (printfs start going in wrong places, it boots out back to disk_init all over again ~ buffer overflow or something?)
Far as I can tell it is the 32bit reads that are causing the problem, for an unsigned number it seems to always return 32 1's and then restarts the program for some odd reason.
Trying to reverse this asm is like playing in a sandbox where I dont get anything, not even sand...
#72510 - chishm - Sun Feb 19, 2006 10:13 am
cory1492 wrote: |
Code: | #define SD_COMS (*(vu16*)(0x09800000))
_Unlock(); //does the unlock
u32 comstat = SD_COMS; |
SD_COMS always returns 0xFCFF or 0b1111110011111111 (whether I specify u16 or u32 for the variable) |
This is because it will always read 16 bits from 0x09800000 (the vu16* bit). If this gets assigned to an unsigned 32 int, the top 16 bits will be filled with 0.
cory1492 wrote: |
Code: | #define SD_COMS (*(vu32*)(0x09800000))
_Unlock(); //does the unlock
u32 comstat = SD_COMS; |
returns 0b11111100111111111111110011111111 (0xFCFFFCFF)
|
This is because you are reading 32 bits from 0x09800000. This behaviour is harder to understand if you aren't familiar with the hardware. Since the GBA cart uses a 16 bit data bus, 32 bit words are transfered in two 16 bit halfwords, starting with the lower halfword. However, the SD register is addressed using only the top address lines. This means the register is viewable at 0x09800000 - 0x09800100 or so (I don't know the exact range, without having an SC SD). So getting back to the 32 bit read, this means both the top and bottom half words are filled with the contents of the register.
cory1492 wrote: |
hence return (0x9800000 == 0xFCFF) should be sufficient
|
The register may not have all the other bits set all the time. Therefore it is better to use a bitwise AND rather than a logical equals. ie Code: |
return !(*(vu16*)0x09800000 & 0x300); |
cory1492 wrote: |
[...] freezes at the for loop just after the while in ReadSector, and then for some odd reason everything goes haywire (printfs start going in wrong places, it boots out back to disk_init all over again ~ buffer overflow or something?) |
This is quite possibly a stack overflow problem.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com
#73005 - cory1492 - Wed Feb 22, 2006 9:28 pm
Thanks again chishm, I didnt realize that the same register would repeat itself for a range of addresses. You helped fill a couple small holes in my & logic understanding and gave me a couple new ideas to try and comprehend how the SD comms are mapped to the GBA port. Looks like Im gonna have to have another fit of hopefully productive tests soon.
Any thoughts on the hangup though? Im not sure why reading a 32bit value off the bus would crash it, I mean, it should be able to do it (even if the data is incorrect) without that kind of problem.
#73152 - tepples - Thu Feb 23, 2006 5:49 pm
cory1492 wrote: |
Any thoughts on the hangup though? Im not sure why reading a 32bit value off the bus would crash it |
Reading 32 bits is the same as two rapid 16-bit reads. Perhaps the hardware can't handle two reads unless they're spaced at least x microseconds apart.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.