16bit resolution PWM wave player with SD card, super lite version.
Dependencies: mbed DirectSPI FastPWM
Supported boards (confirmed):
Nucleo-F030R8
Nucleo-L152RE
Nucleo-F401RE
Nucleo-F411RE
Only compilation is OK (unchecked, but may work):
Nucleo-L073RZ
Nucleo-F334R8
Nucleo-F303RE
Nucleo-F429ZI
Nucleo-F446RE
Nucleo-F446ZE
Nucleo-L476RG
Supported SD card:
SDSC/SDHC card,
FAT16 and FAT32.
(1) At first, format SD card using SD Card Formatter
https://www.sdcard.org/downloads/formatter_4/index.html
(2) Copy PCM wav files to the SD card.
Supported file:
PCM wave file that have file extension ".wav" on root directory.
16bit/8bit, fs(sampling rate)=32kHz,44.1kHz,48kHz.
Stereo/Mono.
Hardware setting:
Refer to the file port_setting.txt
PWM output port:
Left upper(Hi) PWM 8bit out: PB_5 (TM3_CH2)
Right upper(Hi) PWM 8bit out: PB4 (TM3_CH1)
Left lower(Low) PWM 8bit out: PC_9 (TM3_CH4)
Right lower(Low) PWM 8bit out: PC_8 (TM3_CH3)
USER_BUTTON: PC_13(default button)
Next song: One click in Play mode.
Pause : Push long time .
Play : One click from Pause.
fat_lib.cpp@10:1108261dabe8, 2019-01-21 (annotated)
- Committer:
- mimi3
- Date:
- Mon Jan 21 22:17:25 2019 +0900
- Revision:
- 10:1108261dabe8
- Parent:
- 0:9a5c2fb0d96f
so far
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mimi3 | 0:9a5c2fb0d96f | 1 | #include "sys.h" |
mimi3 | 0:9a5c2fb0d96f | 2 | #include "sd_card.h" // -- include the sd card ide hard disk library |
mimi3 | 0:9a5c2fb0d96f | 3 | #include "fat_lib.h" |
mimi3 | 0:9a5c2fb0d96f | 4 | |
mimi3 | 0:9a5c2fb0d96f | 5 | //;sd_init() // -- initialize startup settings |
mimi3 | 0:9a5c2fb0d96f | 6 | |
mimi3 | 10:1108261dabe8 | 7 | #if DEBUG_FAT_LIB |
mimi3 | 10:1108261dabe8 | 8 | extern Serial pc; |
mimi3 | 10:1108261dabe8 | 9 | #endif |
mimi3 | 0:9a5c2fb0d96f | 10 | |
mimi3 | 0:9a5c2fb0d96f | 11 | /****************** |
mimi3 | 0:9a5c2fb0d96f | 12 | definition of global variables |
mimi3 | 0:9a5c2fb0d96f | 13 | *******************/ |
mimi3 | 0:9a5c2fb0d96f | 14 | byte gDirEntryBuff[32]; |
mimi3 | 0:9a5c2fb0d96f | 15 | byte gbBPB_SecPerClus; |
mimi3 | 0:9a5c2fb0d96f | 16 | dword gdwBPB_FileSize; |
mimi3 | 0:9a5c2fb0d96f | 17 | word lgwBPB_BytesPerSec; |
mimi3 | 0:9a5c2fb0d96f | 18 | word gwBPB_RootEntCnt; |
mimi3 | 0:9a5c2fb0d96f | 19 | //-- |
mimi3 | 0:9a5c2fb0d96f | 20 | dword gdwRootdir_sector, gdwTargetFileSector; |
mimi3 | 0:9a5c2fb0d96f | 21 | word gwSize_of_root; |
mimi3 | 0:9a5c2fb0d96f | 22 | sbit gfFat32 ; |
mimi3 | 0:9a5c2fb0d96f | 23 | |
mimi3 | 0:9a5c2fb0d96f | 24 | /****************** |
mimi3 | 0:9a5c2fb0d96f | 25 | FAT_init |
mimi3 | 0:9a5c2fb0d96f | 26 | *******************/ |
mimi3 | 0:9a5c2fb0d96f | 27 | /* |
mimi3 | 0:9a5c2fb0d96f | 28 | ; Refer to ChaN's FAT info page, |
mimi3 | 0:9a5c2fb0d96f | 29 | ; http://elm-chan.org/docs/fat.html#bpb |
mimi3 | 0:9a5c2fb0d96f | 30 | ; Thank you, ChaN san. |
mimi3 | 0:9a5c2fb0d96f | 31 | */ |
mimi3 | 0:9a5c2fb0d96f | 32 | void FAT_init() { |
mimi3 | 0:9a5c2fb0d96f | 33 | byte bi; |
mimi3 | 0:9a5c2fb0d96f | 34 | #define bpbBuff gDirEntryBuff //; shares as temporaly data memory |
mimi3 | 0:9a5c2fb0d96f | 35 | dword dwBPB_SecPerFats32; |
mimi3 | 0:9a5c2fb0d96f | 36 | word wBPB_RsvdSecCnt; |
mimi3 | 0:9a5c2fb0d96f | 37 | dword dwBPB_HiddSec; |
mimi3 | 0:9a5c2fb0d96f | 38 | dword dwBPB_Sector; |
mimi3 | 0:9a5c2fb0d96f | 39 | #if HAVE_FAT32 |
mimi3 | 0:9a5c2fb0d96f | 40 | byte bBPB_NumFATs; |
mimi3 | 0:9a5c2fb0d96f | 41 | #else |
mimi3 | 0:9a5c2fb0d96f | 42 | #define bBPB_NumFATs 2 //; to reduce Flash size |
mimi3 | 0:9a5c2fb0d96f | 43 | #endif |
mimi3 | 0:9a5c2fb0d96f | 44 | |
mimi3 | 0:9a5c2fb0d96f | 45 | sd_start_read(0); // -- read MBR sector |
mimi3 | 0:9a5c2fb0d96f | 46 | #if 0 |
mimi3 | 0:9a5c2fb0d96f | 47 | printf("\n"); |
mimi3 | 0:9a5c2fb0d96f | 48 | for(i=0;i<512;i++){ |
mimi3 | 0:9a5c2fb0d96f | 49 | if((i%16)==0){ printf("\n %04X:",i);}; |
mimi3 | 0:9a5c2fb0d96f | 50 | printf("%02X ",sd_data_byte()); |
mimi3 | 0:9a5c2fb0d96f | 51 | } |
mimi3 | 0:9a5c2fb0d96f | 52 | fflush(stdout); |
mimi3 | 0:9a5c2fb0d96f | 53 | while(1); |
mimi3 | 0:9a5c2fb0d96f | 54 | #endif |
mimi3 | 0:9a5c2fb0d96f | 55 | |
mimi3 | 0:9a5c2fb0d96f | 56 | sd_read_pulse_byte(454); // -- go to partition info |
mimi3 | 0:9a5c2fb0d96f | 57 | low(dwBPB_Sector)[0] = sd_data_byte(); //-- get BPB info sector number |
mimi3 | 0:9a5c2fb0d96f | 58 | low(dwBPB_Sector)[1] = sd_data_byte(); |
mimi3 | 0:9a5c2fb0d96f | 59 | low(dwBPB_Sector)[2] = sd_data_byte(); |
mimi3 | 0:9a5c2fb0d96f | 60 | low(dwBPB_Sector)[3] = sd_data_byte(); |
mimi3 | 0:9a5c2fb0d96f | 61 | sd_stop_read(); |
mimi3 | 0:9a5c2fb0d96f | 62 | |
mimi3 | 0:9a5c2fb0d96f | 63 | sd_start_read(dwBPB_Sector);// -- go to BPB info sector |
mimi3 | 0:9a5c2fb0d96f | 64 | // printf("\n%04X",dwBPB_Sector); |
mimi3 | 0:9a5c2fb0d96f | 65 | // printf("\n "); |
mimi3 | 0:9a5c2fb0d96f | 66 | for(bi=0;bi<32;bi++){ |
mimi3 | 0:9a5c2fb0d96f | 67 | bpbBuff[bi] = sd_data_byte();// -- read BPB info to bpbBuff[] |
mimi3 | 0:9a5c2fb0d96f | 68 | // printf("%02X ",bpbBuff[bi]); |
mimi3 | 0:9a5c2fb0d96f | 69 | } |
mimi3 | 0:9a5c2fb0d96f | 70 | |
mimi3 | 0:9a5c2fb0d96f | 71 | //; register BPB info to each variable |
mimi3 | 0:9a5c2fb0d96f | 72 | low(lgwBPB_BytesPerSec)[0] = bpbBuff[11]; |
mimi3 | 0:9a5c2fb0d96f | 73 | low(lgwBPB_BytesPerSec)[1] = bpbBuff[12]; |
mimi3 | 0:9a5c2fb0d96f | 74 | |
mimi3 | 0:9a5c2fb0d96f | 75 | gbBPB_SecPerClus = bpbBuff[13]; |
mimi3 | 0:9a5c2fb0d96f | 76 | |
mimi3 | 0:9a5c2fb0d96f | 77 | low(wBPB_RsvdSecCnt)[0] = bpbBuff[14]; |
mimi3 | 0:9a5c2fb0d96f | 78 | low(wBPB_RsvdSecCnt)[1] = bpbBuff[15]; |
mimi3 | 0:9a5c2fb0d96f | 79 | #if HAVE_FAT32 |
mimi3 | 0:9a5c2fb0d96f | 80 | bBPB_NumFATs = bpbBuff[16]; |
mimi3 | 0:9a5c2fb0d96f | 81 | #endif |
mimi3 | 0:9a5c2fb0d96f | 82 | |
mimi3 | 0:9a5c2fb0d96f | 83 | low(gwBPB_RootEntCnt)[0] = bpbBuff[17]; |
mimi3 | 0:9a5c2fb0d96f | 84 | low(gwBPB_RootEntCnt)[1] = bpbBuff[18]; |
mimi3 | 0:9a5c2fb0d96f | 85 | //; BPB_FATSz16 |
mimi3 | 0:9a5c2fb0d96f | 86 | low(dwBPB_SecPerFats32)[0]= bpbBuff[22] ; //for FAT16 |
mimi3 | 0:9a5c2fb0d96f | 87 | low(dwBPB_SecPerFats32)[1]= bpbBuff[23] ; //for FAT16 |
mimi3 | 0:9a5c2fb0d96f | 88 | low(dwBPB_SecPerFats32)[2]= 0 ; //for FAT16 |
mimi3 | 0:9a5c2fb0d96f | 89 | low(dwBPB_SecPerFats32)[3]= 0 ; //for FAT16 |
mimi3 | 0:9a5c2fb0d96f | 90 | |
mimi3 | 0:9a5c2fb0d96f | 91 | low(dwBPB_HiddSec)[0] = bpbBuff[28]; |
mimi3 | 0:9a5c2fb0d96f | 92 | low(dwBPB_HiddSec)[1] = bpbBuff[29]; |
mimi3 | 0:9a5c2fb0d96f | 93 | low(dwBPB_HiddSec)[2] = bpbBuff[30]; |
mimi3 | 0:9a5c2fb0d96f | 94 | low(dwBPB_HiddSec)[3] = bpbBuff[31]; |
mimi3 | 0:9a5c2fb0d96f | 95 | |
mimi3 | 0:9a5c2fb0d96f | 96 | #if HAVE_FAT32 |
mimi3 | 0:9a5c2fb0d96f | 97 | if ((low(dwBPB_SecPerFats32)[0] == 0) && (low(dwBPB_SecPerFats32)[1]==0)){ |
mimi3 | 0:9a5c2fb0d96f | 98 | //----- enable FAT32 mode |
mimi3 | 0:9a5c2fb0d96f | 99 | #if DEBUG_FAT_LIB |
mimi3 | 0:9a5c2fb0d96f | 100 | pc.printf("\n FAT32"); |
mimi3 | 0:9a5c2fb0d96f | 101 | #endif |
mimi3 | 0:9a5c2fb0d96f | 102 | gfFat32 = true; |
mimi3 | 0:9a5c2fb0d96f | 103 | bi = sd_data_byte() ;// dummy read |
mimi3 | 0:9a5c2fb0d96f | 104 | bi = sd_data_byte(); |
mimi3 | 0:9a5c2fb0d96f | 105 | bi = sd_data_byte(); |
mimi3 | 0:9a5c2fb0d96f | 106 | bi = sd_data_byte(); |
mimi3 | 0:9a5c2fb0d96f | 107 | //; BPB_FATSz32 |
mimi3 | 0:9a5c2fb0d96f | 108 | low(dwBPB_SecPerFats32)[0] = sd_data_byte(); |
mimi3 | 0:9a5c2fb0d96f | 109 | low(dwBPB_SecPerFats32)[1] = sd_data_byte(); |
mimi3 | 0:9a5c2fb0d96f | 110 | low(dwBPB_SecPerFats32)[2] = sd_data_byte(); |
mimi3 | 0:9a5c2fb0d96f | 111 | low(dwBPB_SecPerFats32)[3] = sd_data_byte(); |
mimi3 | 0:9a5c2fb0d96f | 112 | } |
mimi3 | 0:9a5c2fb0d96f | 113 | #endif |
mimi3 | 0:9a5c2fb0d96f | 114 | |
mimi3 | 0:9a5c2fb0d96f | 115 | //; /* Root DIR start sector : (absolute sector) */ |
mimi3 | 0:9a5c2fb0d96f | 116 | gdwRootdir_sector = ( dwBPB_SecPerFats32 * bBPB_NumFATs ) |
mimi3 | 0:9a5c2fb0d96f | 117 | + wBPB_RsvdSecCnt |
mimi3 | 0:9a5c2fb0d96f | 118 | + dwBPB_HiddSec; |
mimi3 | 0:9a5c2fb0d96f | 119 | |
mimi3 | 0:9a5c2fb0d96f | 120 | gwSize_of_root = gwBPB_RootEntCnt * 32; |
mimi3 | 0:9a5c2fb0d96f | 121 | |
mimi3 | 0:9a5c2fb0d96f | 122 | //;include debug_info1 |
mimi3 | 0:9a5c2fb0d96f | 123 | sd_stop_read(); |
mimi3 | 0:9a5c2fb0d96f | 124 | } |
mimi3 | 0:9a5c2fb0d96f | 125 | |
mimi3 | 0:9a5c2fb0d96f | 126 | /****************** |
mimi3 | 0:9a5c2fb0d96f | 127 | readDirEntry |
mimi3 | 0:9a5c2fb0d96f | 128 | *******************/ |
mimi3 | 0:9a5c2fb0d96f | 129 | void readDirEntry(word wDestDirEntryIndex){ |
mimi3 | 0:9a5c2fb0d96f | 130 | byte i; |
mimi3 | 0:9a5c2fb0d96f | 131 | word wCurrentDirEntryIndex = 0; |
mimi3 | 0:9a5c2fb0d96f | 132 | |
mimi3 | 0:9a5c2fb0d96f | 133 | sd_start_read( gdwRootdir_sector ); |
mimi3 | 0:9a5c2fb0d96f | 134 | #if DEBUG_FAT_LIB |
mimi3 | 0:9a5c2fb0d96f | 135 | pc.printf("\n"); |
mimi3 | 0:9a5c2fb0d96f | 136 | #endif |
mimi3 | 0:9a5c2fb0d96f | 137 | while( true ){ |
mimi3 | 0:9a5c2fb0d96f | 138 | for(i=0;i<32;i++){ //; read one dir entry |
mimi3 | 0:9a5c2fb0d96f | 139 | gDirEntryBuff[i] = sd_data_byte(); |
mimi3 | 0:9a5c2fb0d96f | 140 | #if DEBUG_FAT_LIB |
mimi3 | 0:9a5c2fb0d96f | 141 | pc.printf("%02X ",gDirEntryBuff[i]); |
mimi3 | 0:9a5c2fb0d96f | 142 | #endif |
mimi3 | 0:9a5c2fb0d96f | 143 | } |
mimi3 | 0:9a5c2fb0d96f | 144 | if( wCurrentDirEntryIndex == wDestDirEntryIndex) { |
mimi3 | 0:9a5c2fb0d96f | 145 | break; |
mimi3 | 0:9a5c2fb0d96f | 146 | } |
mimi3 | 0:9a5c2fb0d96f | 147 | wCurrentDirEntryIndex = wCurrentDirEntryIndex + 32; |
mimi3 | 0:9a5c2fb0d96f | 148 | if( !gfFat32 ){ |
mimi3 | 0:9a5c2fb0d96f | 149 | if (wCurrentDirEntryIndex >= gwSize_of_root){ |
mimi3 | 0:9a5c2fb0d96f | 150 | break; |
mimi3 | 0:9a5c2fb0d96f | 151 | } |
mimi3 | 0:9a5c2fb0d96f | 152 | } |
mimi3 | 0:9a5c2fb0d96f | 153 | } |
mimi3 | 0:9a5c2fb0d96f | 154 | sd_stop_read(); |
mimi3 | 0:9a5c2fb0d96f | 155 | } |
mimi3 | 0:9a5c2fb0d96f | 156 | |
mimi3 | 0:9a5c2fb0d96f | 157 | /****************** |
mimi3 | 0:9a5c2fb0d96f | 158 | searchNexFile |
mimi3 | 0:9a5c2fb0d96f | 159 | *******************/ |
mimi3 | 0:9a5c2fb0d96f | 160 | void searchNextFile(){ |
mimi3 | 0:9a5c2fb0d96f | 161 | byte topChar; |
mimi3 | 0:9a5c2fb0d96f | 162 | dword dwTargetClusterNumber; |
mimi3 | 0:9a5c2fb0d96f | 163 | dword ldwRootdir_sector_size; |
mimi3 | 0:9a5c2fb0d96f | 164 | static word wNextDirEntryIndex = 0; // ; initialize |
mimi3 | 0:9a5c2fb0d96f | 165 | |
mimi3 | 0:9a5c2fb0d96f | 166 | if( wNextDirEntryIndex != 0) {// ; if 0 , search first song |
mimi3 | 0:9a5c2fb0d96f | 167 | wNextDirEntryIndex = wNextDirEntryIndex + 32 ; //search next song |
mimi3 | 0:9a5c2fb0d96f | 168 | } |
mimi3 | 0:9a5c2fb0d96f | 169 | |
mimi3 | 0:9a5c2fb0d96f | 170 | while (true) { //; start dir entry search |
mimi3 | 0:9a5c2fb0d96f | 171 | //; skip deleted entry |
mimi3 | 0:9a5c2fb0d96f | 172 | while (true) { |
mimi3 | 0:9a5c2fb0d96f | 173 | readDirEntry(wNextDirEntryIndex); |
mimi3 | 0:9a5c2fb0d96f | 174 | topChar = gDirEntryBuff[0]; |
mimi3 | 0:9a5c2fb0d96f | 175 | if( topChar == 0xE5) { //; skip deleted entry |
mimi3 | 0:9a5c2fb0d96f | 176 | wNextDirEntryIndex = wNextDirEntryIndex + 32; |
mimi3 | 0:9a5c2fb0d96f | 177 | }else if(topChar == 0){ |
mimi3 | 0:9a5c2fb0d96f | 178 | //; dir entry table is end, so return to the top entry |
mimi3 | 0:9a5c2fb0d96f | 179 | wNextDirEntryIndex = 0; |
mimi3 | 0:9a5c2fb0d96f | 180 | }else{ |
mimi3 | 0:9a5c2fb0d96f | 181 | break; |
mimi3 | 0:9a5c2fb0d96f | 182 | } |
mimi3 | 0:9a5c2fb0d96f | 183 | } |
mimi3 | 0:9a5c2fb0d96f | 184 | //; check long file name |
mimi3 | 0:9a5c2fb0d96f | 185 | if((topChar >= 0x42) && (topChar <= 0x54)) { |
mimi3 | 0:9a5c2fb0d96f | 186 | if( ( gDirEntryBuff[11] & 0x0F ) == 0x0F) { //; long file name ID(=0x0F) or not |
mimi3 | 0:9a5c2fb0d96f | 187 | //; this is long file name, so set index to short file name address |
mimi3 | 0:9a5c2fb0d96f | 188 | wNextDirEntryIndex = wNextDirEntryIndex + ((word)((topChar - 0x40))<<5); |
mimi3 | 0:9a5c2fb0d96f | 189 | readDirEntry(wNextDirEntryIndex); |
mimi3 | 0:9a5c2fb0d96f | 190 | } |
mimi3 | 0:9a5c2fb0d96f | 191 | } |
mimi3 | 0:9a5c2fb0d96f | 192 | |
mimi3 | 0:9a5c2fb0d96f | 193 | //;get the file extention |
mimi3 | 0:9a5c2fb0d96f | 194 | if( (gDirEntryBuff[8] =='W') && (gDirEntryBuff[9] =='A') |
mimi3 | 0:9a5c2fb0d96f | 195 | && (gDirEntryBuff[10]=='V') && (gDirEntryBuff[11]==' ')) { |
mimi3 | 0:9a5c2fb0d96f | 196 | // ; gDirEntryBuff[11]=" ": (space) is the mark of archive attribute |
mimi3 | 0:9a5c2fb0d96f | 197 | // ; if the file extention matches 'WAV ', break |
mimi3 | 0:9a5c2fb0d96f | 198 | // ----------- |
mimi3 | 0:9a5c2fb0d96f | 199 | break; |
mimi3 | 0:9a5c2fb0d96f | 200 | //----------- |
mimi3 | 0:9a5c2fb0d96f | 201 | } |
mimi3 | 0:9a5c2fb0d96f | 202 | //; for read next entry |
mimi3 | 0:9a5c2fb0d96f | 203 | wNextDirEntryIndex = wNextDirEntryIndex + 32; |
mimi3 | 0:9a5c2fb0d96f | 204 | } //; end while: dir entry search |
mimi3 | 0:9a5c2fb0d96f | 205 | |
mimi3 | 0:9a5c2fb0d96f | 206 | #if UART_INFO |
mimi3 | 0:9a5c2fb0d96f | 207 | //-- print out music file name(short file name) to UART |
mimi3 | 0:9a5c2fb0d96f | 208 | static int ix=0; |
mimi3 | 0:9a5c2fb0d96f | 209 | byte fname[13]; |
mimi3 | 10:1108261dabe8 | 210 | for(int i=0;i<8;i++){ fname[i] = gDirEntryBuff[i]; } |
mimi3 | 0:9a5c2fb0d96f | 211 | fname[8] = '.'; |
mimi3 | 0:9a5c2fb0d96f | 212 | fname[9] = gDirEntryBuff[8]; |
mimi3 | 0:9a5c2fb0d96f | 213 | fname[10] = gDirEntryBuff[9]; |
mimi3 | 0:9a5c2fb0d96f | 214 | fname[11] = gDirEntryBuff[10]; |
mimi3 | 0:9a5c2fb0d96f | 215 | fname[12] = 0; |
mimi3 | 0:9a5c2fb0d96f | 216 | printf("\n[%3d]: %s",ix++,fname); |
mimi3 | 0:9a5c2fb0d96f | 217 | #endif |
mimi3 | 0:9a5c2fb0d96f | 218 | |
mimi3 | 0:9a5c2fb0d96f | 219 | if (gfFat32) { |
mimi3 | 0:9a5c2fb0d96f | 220 | low(dwTargetClusterNumber)[2] = (gDirEntryBuff[20]); |
mimi3 | 0:9a5c2fb0d96f | 221 | low(dwTargetClusterNumber)[3] = (gDirEntryBuff[21]); |
mimi3 | 0:9a5c2fb0d96f | 222 | }else{ |
mimi3 | 0:9a5c2fb0d96f | 223 | low(dwTargetClusterNumber)[2] = 0; |
mimi3 | 0:9a5c2fb0d96f | 224 | low(dwTargetClusterNumber)[3] = 0; |
mimi3 | 0:9a5c2fb0d96f | 225 | } |
mimi3 | 0:9a5c2fb0d96f | 226 | low(dwTargetClusterNumber)[0] = (gDirEntryBuff[26]); |
mimi3 | 0:9a5c2fb0d96f | 227 | low(dwTargetClusterNumber)[1] = (gDirEntryBuff[27]); |
mimi3 | 0:9a5c2fb0d96f | 228 | |
mimi3 | 0:9a5c2fb0d96f | 229 | low(gdwBPB_FileSize)[0] = (gDirEntryBuff[28]); // file size |
mimi3 | 0:9a5c2fb0d96f | 230 | low(gdwBPB_FileSize)[1] = (gDirEntryBuff[29]); |
mimi3 | 0:9a5c2fb0d96f | 231 | low(gdwBPB_FileSize)[2] = (gDirEntryBuff[30]); |
mimi3 | 0:9a5c2fb0d96f | 232 | low(gdwBPB_FileSize)[3] = (gDirEntryBuff[31]); |
mimi3 | 0:9a5c2fb0d96f | 233 | |
mimi3 | 0:9a5c2fb0d96f | 234 | ldwRootdir_sector_size = (32 * (dword)(gwBPB_RootEntCnt) + lgwBPB_BytesPerSec - 1 ) / lgwBPB_BytesPerSec; |
mimi3 | 0:9a5c2fb0d96f | 235 | |
mimi3 | 0:9a5c2fb0d96f | 236 | //; calculate start sector of target song file |
mimi3 | 0:9a5c2fb0d96f | 237 | gdwTargetFileSector = gdwRootdir_sector + ldwRootdir_sector_size |
mimi3 | 0:9a5c2fb0d96f | 238 | + (dwTargetClusterNumber - 2) * gbBPB_SecPerClus; |
mimi3 | 0:9a5c2fb0d96f | 239 | |
mimi3 | 0:9a5c2fb0d96f | 240 | //;include debug_info2 |
mimi3 | 0:9a5c2fb0d96f | 241 | } |
mimi3 | 0:9a5c2fb0d96f | 242 |