Notes on parsing the boot sector of the SD Card with the goal of reading in the directory.
The boot sector is documented in this log.
The first important data structure on a FAT volume is called the BPB (BIOS Parameter Block), which is located in the first sector of the volume in the Reserved Region. This sector is sometimes called the “boot sector” or the “reserved sector” or the “0th sector,” but the important fact is simply that it is the first sector of the volume. All the fields whose names start with BPB_ are part of the BPB.
Significant locations are <values in brackets are what I read from my SD Card>:
14-15 BPB_RsvdSecCnt Number of reserved sectors (1) FAT32 uses 32. <0x083a> = 2106 decimal 16 BPB_NumFATs Number of FAT copies <0x02> 36-39 BPB_FATSz32 Sectors per FAT <0x00003BE3> = 15331 dec
FirstDataSector = BPB_RsvdSecCnt + (BPB_NumFATs * BPB_FATSz32) + RootDirSectors;
For FAT32, RootDirSectors = 0
= 2106 + (2 * 15331) + 0
= 32,768
The sector there is:
Batch file to compile and make files:
cl65 --start-addr 0x300 -Wl -D,__HIMEM__=$2000,-D,__STACKSIZE__=$0200 -t osic1p -vm -m OSISDOS.map -o OSISDOS.o OSISDOS.c "C:\Users\HPz420\Documents\GitHub\Doug Gilliland\Retro-Computers\6502\RetroAssembler\retroassembler.exe" -d -D=0x0300 OSISDOS.o OSISDOS.DIS "..\..\..\..\..\PC Tools\srecord\srec_cat.exe" OSISDOS.o -bin -of 0x300 -o OSISDOS.c1p -os -esa=0x300
Got the code to read the directory working in C. It is convenient that the endianness of the values matches what reading longs and shorts in C use so there's no need to shuffle the endian values or read as bytes and pack into shorts and long values.
/* main - Test the SD Card interface */
void main(void)
{
unsigned long dirSectorNumber;
unsigned short sectorCount;
unsigned char numFATs;
unsigned long FATSz;
*(unsigned char*) BANK_SELECT_REG_ADR = 0x00; /* Set bank register to first bank */
readSector((unsigned long)0); /* Master boot record at sector 0 */
/* Get the sector count, number of FATs, and FAt size */
sectorCount = * (unsigned long *) (READ_BUFFER_START + BPB_RsvdSecCnt_16);
numFATs = * (unsigned char *) (READ_BUFFER_START + BPB_NumFATs_8);
FATSz = * (unsigned long *) (READ_BUFFER_START + BPB_FATSz32_32);
/* Assumes that numFATs = 2 */
/* Do the math to find the directory sector */
dirSectorNumber = sectorCount + (FATSz << 1);
/* Read the directory into the bank SRAM*/
readSector(dirSectorNumber);
}
Next step is to go from the directory to a file.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.