In the previous log I got the directory to read into the RAMDISK space. This step will go from the directory to a file. This page gives a nice synopsis.
From my previous log, the directory on my SD card looks like:
Directory entries are in 32-byte blocks, for instance the RAMTEST.BAS entry has:
The Microsoft Extensible Firmware Initiative FAT32 File System Specification provides additional information in tabular form
Name | Offset (byte) | Size (bytes) | Description |
DIR_Name | 0 | 11 | Short name.
<RAMTEST BAS> |
DIR_Attr | 11 | 1 | File attributes: ATTR_READ_ONLY 0x01 ATTR_HIDDEN 0x02 ATTR_SYSTEM 0x04 ATTR_VOLUME_ID 0x08 ATTR_DIRECTORY 0x10 ATTR_ARCHIVE 0x20 ATTR_LONG_NAME ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID The upper two bits of the attribute byte are reserved and should always be set to 0 when a file is created and never modified or looked at after that. <0x20> |
DIR_NTRes | 12 | 1 | Reserved for use by Windows NT.
Set value to 0 when a file is created and never modify or look at it after that. <0x00> |
DIR_CrtTimeTenth | 13 | 1 | Millisecond stamp at file creation time.
This field actually contains a count of tenths of a second. The granularity of the seconds part of DIR_CrtTime is 2 seconds so this field is a count of tenths of a second and its valid value range is 0-199 inclusive. <0xA7> |
DIR_FstClusHI | 20 | 2 | High word of this entry’s first cluster number
(always 0 for a FAT12 or FAT16 volume). <0x0000> |
DIR_WrtTime | 22 | 2 | Time of last write. Note that file creation is considered a write. <0x00DD> |
DIR_WrtDate | 24 | 2 | Date of last write. Note that file creation is considered a write. <0xF9A4> |
DIR_FstClusLO | 26 | 2 | Low word of this entry’s first cluster number. <0x0007> = 7 dec |
DIR_FileSize | 28 | 4 | 32-bit DWORD holding this file’s size in bytes. <0x0000019C> = 412 dec |
So, the cluster number for RAMTEST.BAS is 56. From the boot record, there are 8 sectors per cluster.
13 BPB_SecPerClus Number of sectors per cluster (1) Must be one of 1, 2, 4, 8, 16, 32, 64, 128. A cluster should have at most 32768 bytes. In rare cases 65536 is OK. <0x08> = 8 sectors per clusters
That means the file starts at cluster 7 * 8 = 56. This should be relative to the FirstDataSector calculated above to be 32,768. So the first sector number for RAMTEST.BAS should be at 32,768+56=32,824. However, the file is actually 16 sectors earlier at sector 32,808. Must be an offset of 2 clusters?
Here's the answer:
Looking at the hex dump
- DISKREAD.BAS is at sector 32,800 (32,768 + 32).
- RAMTEST.BAS is at sector 32,808 (32,768+40).
- BANKTEST.BAS is at sector 32,816 (32,768+56).
I get the same result from the BASIC program. LBA1 = 0x80 which is 32768.
RUN LBA0 ? 40 LBA1 ? 128 LBA2 ? 0 SD CTRLR STAT = 128 20 31 30 30 20 52 45 4D 20 54 45 53 54 20 55 50 100 REM TEST UP 50 45 52 20 4D 45 4D 4F 52 59 0D 0A 20 31 31 30 PER MEMORY.. 110 20 52 45 4D 20 55 50 50 45 52 20 4D 45 4D 4F 52 REM UPPER MEMOR 59 20 49 53 20 34 4B 42 20 46 52 4F 4D 20 24 45 Y IS 4KB FROM $E 30 30 30 2D 24 45 46 46 46 20 28 35 37 33 34 34 000-$EFFF (57344 2D 36 31 34 33 39 20 44 45 43 29 0D 0A 20 31 32 -61439 DEC).. 12 30 20 53 3D 35 37 33 34 34 0D 0A 20 31 33 30 20 0 S=57344.. 130 45 3D 36 31 34 33 39 0D 0A 20 32 30 30 20 52 45 E=61439.. 200 RE 4D 20 46 49 4C 4C 20 4D 45 4D 4F 52 59 0D 0A 20 M FILL MEMORY.. 32 31 30 20 50 3D 30 0D 0A 20 32 32 30 20 46 4F 210 P=0.. 220 FO 52 20 41 3D 53 20 54 4F 20 45 0D 0A 20 32 33 30 R A=S TO E.. 230 20 50 4F 4B 45 20 41 2C 50 0D 0A 20 32 34 30 20 POKE A,P.. 240 50 3D 50 2B 31 0D 0A 20 32 35 30 20 50 3D 50 20 P=P+1.. 250 P=P 41 4E 44 20 32 35 35 0D 0A 20 32 36 30 20 4E 45 AND 255.. 260 NE 58 54 20 41 0D 0A 20 33 30 30 20 52 45 4D 20 56 XT A.. 300 REM V 45 52 49 46 59 20 46 49 4C 4C 45 44 20 4D 45 4D ERIFY FILLED MEM 4F 52 59 0D 0A 20 33 31 30 20 58 3D 30 0D 0A 20 ORY.. 310 X=0.. 33 32 30 20 46 4F 52 20 41 3D 53 20 54 4F 20 45 320 FOR A=S TO E 0D 0A 20 33 33 30 20 50 3D 50 45 45 4B 28 41 29 .. 330 P=PEEK(A) 0D 0A 20 33 34 30 20 49 46 20 50 3C 3E 58 20 47 .. 340 IF P<>X G 4F 54 4F 20 35 30 30 0D 0A 20 33 35 30 20 58 3D OTO 500.. 350 X= 58 2B 31 0D 0A 20 33 36 30 20 58 3D 58 20 41 4E X+1.. 360 X=X AN 44 20 32 35 35 0D 0A 20 33 37 30 20 4E 45 58 54 D 255.. 370 NEXT 20 41 0D 0A 20 33 38 30 20 45 4E 44 0D 0A 20 35 A.. 380 END.. 5 30 30 20 50 52 49 4E 54 22 45 52 52 4F 52 22 0D 00 PRINT"ERROR". 0A 20 35 31 30 20 45 4E 44 0D 0A 20 00 00 00 00 . 510 END.. .... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
So, the sector number of a particular file on the SD Card from the directory is:
LBA = FirstDataSector + ((((DIR_FstClusHI << 16) + (DIR_FstClusHLo)) - 2) * BPB_SecPerClus )
For RAMTEST.BAS:
- FirstDataSector = 32,768 Found earlier when the first sector of the data was found
- DIR_FstClusHI = 0x0000 - High 16-bits of first cluster
- DIR_FstClusHLo = 0x0007 - Low 16-bits of first cluster
- BPB_SecPerClus = 0x08 - Sectors per cluster
So, the LBA for RAMTEST.BAS should be:
= 32,768 + * ( ( (0x0000<<16) + (0x0007) ) - 2) * 8)
= 32,768+40
= 32,808
Which is correct!
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.