post
Pessoal,
\n
\nSegue um projeto muito interessante, que foi publicado recentemente no fórum oficial do Bascom. Como é algo diferente, pedà autorização para o autor para publicar aqui, no que fui atendido.
\n
\nÉ um simples tocador de arquivos .wav colocados em uma mÃdia tipo SD card, o interessante é que apresenta uma qualidade de reprodução muito boa sem usar nenhum hardware especial, apenas um circuito RC ligado numa saÃda de PWM.
\n
\nDe imediato , nota-se o uso de um cristal oscilador de 32 Mhz !!!!!!
\n
\nO datasheet dos Atmegas especifica uma frequência máxima de 20 Mhz, mas o autor e outros usuários confirmam que o Atmega8, Atmega32 e o Atmega328 rodam prefeitamente a 32 Mhz, desde que seja usado um circuito oscilador externo.
\n
\nJá imaginaram a potência disso ??? é quase 3 vezes o desempenho da famÃlia PIC18F ......
\n
\nSegue a foto da montagem do autor :
\n
\n
\n[url=http://postimg.org/image/hv2lnovq1/][img]http://s12.postimg.org/hv2lnovq1/player_sd_card_wav_137.jpg[/img][/url]
\n
\nO programa é composto de dois módulos, um deles possui várias definições de variáveis.
\n
\nSegue o programa principal :
\n
\n[code]' using bascom 2.073
\n' wave player 8 bit 22 khz mono
\n' by noel benoit
\n' using kokkekat
\n' external oscillator 32mhz
\n
\n$regfile = "m8def.dat"
\n$crystal = 32000000
\n$framesize = 25
\n$hwstack = 25
\n$swstack = 25
\n' added code from line 689 to line 823 IN function sdreadsector modified for playing wave
\n$include "KokkeKat_FAT-free_SD_lib_decl32.bas"
\n Config Portd = Output
\nConfig Lcd = 16 * 2 ' Config Lcd = 40 * 2
\nConfig Lcdpin = Pin , Db4 = Portd.3 , Db5 = Portd.2 , Db6 = Portd.1 , Db7 = Portd.0 , E = Portd.4 , Rs = Portd.5
\n'port 4 et 5 ok
\n'--------------------variable audio ------------------------------------------------------
\n'Initlcd
\nDim Buffer1(258) As Byte
\n'dim buffer2 (128) as byte
\nDim X1 As Word
\nDim X2 As Word
\nDim X3 As Word
\nDim Calc As Long
\nSpsr = 1 ' double speed spi if 1
\nDim Read_sound As Byte 'allow reading sound
\nDim Pointer_sd As Bit
\nDim Turn As Byte 'number ofthe musiv to play 'T0 CLOCK
\n'---------------------config timer ----------------------------------------------
\nEnable Interrupts
\nEnable Timer2
\nConfig Timer1 = Pwm , Prescale = 1 , Compare A = Clear , Pwm = 8 ', Noise_cancel = 1
\nConfig Portb.1 = Output
\nConfig Timer2 = Counter , Prescale = 8
\nOn Ovf2 Interuption_timer2:
\nStop Timer2
\n '-------------------------------------------------------------------------------
\n
\n '----------------------------------------------------------------------------------
\nDim Sdtempw2 As Word ' Only needed for the examples
\nDim Sddebug As Byte ' Only needed for the examples
\nDim Sdstr As String * 1
\n
\n
\nPointer_sd = 0
\n ' tempo2
\nSdsecincluster = 1 ' config for first search
\nSdbufferpos = 1 ' config for first search
\n
\nTurn = 0 'play music number 0
\nDebut:
\n '**************** start music to play at 8 bit 22KHZ **********************
\n If Turn = 0 Then Sdentrynames = "CHO822 "
\n If Turn = 1 Then Sdentrynames = "VIRUS "
\n If Turn = 2 Then Sdentrynames = "KYLIE822 "
\n If Turn = 3 Then Sdentrynames = "18 "
\n If Turn = 4 Then Sdentrynames = "ICE822 "
\n If Turn = 5 Then Sdentrynames = "15 "
\n '**************** end music to play at 8 bit 22KHZ **********************
\n
\n
\n
\nRead_sound = 0
\nPointer_sd = 0
\nCls
\nLocate 1 , 1
\nLcd "init carte"
\nSet Portc.1
\nWait 3
\n'gosub Sdinit
\n'************** sdinit ***************
\n Sdinit:
\n
\n Sdstatus = 9 ' Minimum initialization detail unspecified error 2
\n
\n Set Sd_cs ' Pull CS high
\n
\n Sdcommand = &HFF ' Send at least 74 clock cycles with cs high
\n For Sdtempb = 1 To 74
\n Gosub Sdcommand1
\n Next Sdtempb
\n
\n Reset Sd_cs
\n
\n Gosub Sdcommand1 ' Send 8 additional clock cycles with cs low
\n
\n Sdcommand = &H40 ' Send CMD0: &H40 &H00 &H00 &H00 &H00 &H95
\n Gosub Sdcommand1
\n Sdcommand = &H00
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Sdcommand = &H95
\n Gosub Sdcommand1
\n
\n Gosub Sdresponseloop ' Receive the single byte of response
\n
\n If Sdresponse(1) = &B00000001 Then ' CMD0 was successful
\n
\n Sdcommand = &HFF ' Send 8 additional clock cycles with cs low
\n Gosub Sdcommand1 ' The SanDisk Extreme III 4GB class 6 requires this
\n
\n Sdcommand = &H48 ' Send CMD8: &H48 &H00 &H00 &H01 &HAA &H87
\n Gosub Sdcommand1
\n Sdcommand = &H00 ' If the response to CMD8 is the same, we have a v2.0 compliant card
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Sdcommand = &H01 ' xxxx0001 specifies voltage range 2.7-3.6V
\n Gosub Sdcommand1
\n Sdcommand = &HAA ' Check pattern 10101010 as recommended
\n Gosub Sdcommand1
\n Sdcommand = &H87
\n Gosub Sdcommand1
\n
\n Gosub Sdresponseloop ' Receive the single byte of response
\n If Sdresponse(1) <> 255 Then ' No timeout in CMD8
\n
\n If Sdresponse(1).2 = 1 Then
\n Sdcardtype = 1 ' R1 illegal command in this case means v1.x SD card
\n Else
\n Sdcardtype = 2 ' v2+
\n Gosub Sdresponse2_5 ' Read the remaining 5 bytes (The first byte has already been checked and the last byte is only sent with CRC enabled)
\n If Sdresponse(1) <> &B00000001 Or Sdresponse(2) <> &H00 Or Sdresponse(3) <> &H00 Or Sdresponse(4) <> &H01 Or Sdresponse(5) <> &HAA Then ' Check if the CMD8 R7 response bytes 2-5 are identical to the command
\n Sdstatus = 8 ' Minimum Initialization Detail Unspecified Error 1
\n End If
\n End If
\n
\n ' Sdstatus = 0 & Sdcardtype = 1 -> v1.x
\n ' Sdstatus = 0 & Sdcardtype = 2 -> v2+
\n
\n If Sdstatus = 9 Then ' Correct response after CMD8
\n
\n Sdcommand = &HFF ' Send 8 additional clock cycles with cs low
\n Gosub Sdcommand1 ' The SanDisk Extreme III 4GB class 6 requires this
\n
\n Sdcommand = &H7A ' Send the first CMD58: &H7A &H00 &H00 &H00 &H00 &HFD
\n Gosub Sdcommand1
\n Sdcommand = &H00
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Sdcommand = &HFD
\n Gosub Sdcommand1
\n
\n Gosub Sdresponseloop ' Receive the single byte of response
\n If Sdresponse(1) <> 255 Then ' No timeout after CMD58
\n
\n Gosub Sdresponse2_5 ' Check OCR register response in bytes 2 & 3
\n If Sdresponse(1) = &B00000001 And Sdresponse(3) = 255 And Sdresponse(4).7 = 1 Then ' There are 9 voltage ranges 2.7 - 3.6V. All must be supported according to spec. OCR bit 15-23 must be high.
\n ' The SD card is in a valid supply voltage
\n Sdtempw = 0
\n Do ' Send <= 64k times CMD55+CMD41
\n Sdcommand = &HFF ' Send 8 additional clock cycles with cs low
\n Gosub Sdcommand1
\n
\n Sdcommand = &H77 ' Send CMD55 (required before all ACMD commands): &H77 &H00 &H00 &H00 &H00 &H65
\n Gosub Sdcommand1
\n Sdcommand = &H00
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Sdcommand = &H65
\n Gosub Sdcommand1
\n
\n
\n Gosub Sdresponseloop ' Receive the single byte of response
\n If Sdresponse(1) <> 255 Then ' No timeout after CMD55
\n
\n Set Sd_cs ' Set CS, clock out 8 bits and reset CS
\n Sdcommand = &HFF
\n Gosub Sdcommand1
\n Reset Sd_cs
\n
\n Sdcommand = &H69 ' Send CMD41: &H69 &H00 &H00 &H00 &H00 &HE5 ' SDSC compatible card (HDS = 0)
\n Gosub Sdcommand1 ' Send CMD41: &H69 &H40 &H00 &H00 &H00 &H77 ' SDHC / SDXC compatible card (HDS = 1)
\n If Sdcardtype = 1 Then ' SDSC compatible card (HDS = 0)
\n Sdcommand = &H00
\n Else ' SDHC / SDXC compatible card (HDS = 1)
\n Sdcommand = &H40
\n End If
\n Gosub Sdcommand1
\n Sdcommand = &H00
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n If Sdcardtype = 1 Then ' SDSC compatible card (HDS = 0)
\n Sdcommand = &HE5
\n Else ' SDHC / SDXC compatible card (HDS = 1)
\n Sdcommand = &H77
\n End If
\n Gosub Sdcommand1
\n
\n Gosub Sdresponseloop ' Receive the single byte of response
\n
\n End If
\n
\n Incr Sdtempw
\n
\n Loop Until Sdresponse(1) = 0 Or Sdtempw = &HFFFF ' The sample cards' loop counts were 62 (Kingston 4GB C2), 56 (SanDisk Extreme III 4GB C6), 49 (SanDisk v2+ 1GB), 115 (Canon 32MB v1.x), and 558 (Transcend v2+ 64GB)
\n
\n If Sdresponse(1) <> 255 Then ' The SD card has accepted the host
\n
\n Sdstatus = 0 ' Initialization complete
\n
\n If Sdcardtype = 2 Then ' For v2+ cards, an additional CMD58 is required according to spec.
\n ' Some cards can respond the CCS info before ACMD41 (Kingston 4GB CL2),
\n ' but 3 of my 4 cards could only return the voltage bits in the previous response.
\n
\n Sdcommand = &HFF ' Send 8 additional clock cycles with cs low
\n Gosub Sdcommand1
\n
\n Sdcommand = &H7A ' Send second CMD58: &H7A &H00 &H00 &H00 &H00 &HFD
\n Gosub Sdcommand1
\n Sdcommand = &H00
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Sdcommand = &HFD
\n Gosub Sdcommand1
\n
\n Gosub Sdresponseloop ' Receive the single byte of response
\n If Sdresponse(1) <> 255 Then ' No timeout in CMD8
\n
\n Gosub Sdresponse2_5 ' Check OCR register response in byte 2
\n
\n If Sdresponse(1) = 0 And Sdresponse(2).7 <> 0 Then
\n If Sdresponse(2).6 = 1 Then ' Card capacity status CCS bit. If it is 1, then Sdcardtype = 2 (previously set)
\n Sdcardtype = 3 ' 1 = v1.x SDSC, 2 = v2+ SDSC, 3 = v2+ SDHC/SDXC
\n End If
\n End If
\n End If
\n End If
\n End If
\n End If
\n End If
\n End If
\n End If
\n End If ' Close CMD8
\n
\n Set Sd_cs
\n
\n ' Sdcommand = &HFF ' Clock SD to complete job
\n ' Gosub Sdcommand1
\n
\n ' In SPI mode, speed is not guaranteed by specification, but the minimum supported 4-bit bus mode clock speed is 12,5 MHz.
\n ' The maximum SPI speed for AVR 8-bit is 10MHz, so we set SPI to maximum speed, f osc / 2
\n 'Spsr.0 = 1 ' Double speed (results in f osc / 2)
\n 'Spcr.1 = 0 ' f osc / 4
\n 'Spcr.0 = 0
\n
\n ' Spcr.1 = 0 ' f osc / 16
\n ' Spcr.0 = 1
\n
\n ' Spcr.1 = 1 'f osc / 64
\n ' Spcr.0 = 0
\n
\n ' Spcr.1 = 1 ' f osc / 128
\n ' Spcr.0 = 1
\n
\n'*********** sd init end *****************
\n
\nIf Sdstatus = 0 Then ' Initialization succesful. Sdcardtype = 1 -> v1.x SDSC, 2 -> v2+ SDSC, 3 -> v2+ SDHC or SDXC
\nLocate 2 , 1
\n Lcd "init ok" ;
\n Wait 1
\n
\n ' Gosub Sdrequestcsd
\n ' Gosub Sdcalculatesize
\n ' Gosub Sdrequeststatus
\n
\n
\n
\n 'Gosub Sdinitfs
\n '*************** sdinitfs *************
\n
\n Sdsectord = 0 ' Read the boot sector
\n Gosub Sdreadsector
\n If Sdstatus = 0 Then
\n
\n
\n ' Locate the start of the BRB (Boot Record Block)
\n If Sdbuffer(1) = &HEB And Sdbuffer(3) = &H90 Then ' Sdsectord is already 0
\n Elseif Sdbuffer(1) = &HE9 Then ' Sdsectord is already 0
\n Else
\n Sdsectorb(1) = Sdbuffer(&H1c7) ' Sector number of first partition
\n Sdsectorb(2) = Sdbuffer(&H1c8)
\n Sdsectorb(3) = Sdbuffer(&H1c9)
\n Sdsectorb(4) = Sdbuffer(&H1ca)
\n Gosub Sdreadsector ' Read the boot record
\n End If
\n
\n #if Sdusewipe = 1
\n Sdpartstart = Sdsectord
\n #endif
\n
\n If Sdstatus = 0 Then
\n
\n ' Value Description
\n ' 00h Unknown Or Nothing
\n ' 01h 12-bit FAT
\n ' 04h 16-bit FAT (Partition Smaller than 32MB)
\n ' 05h Extended MS-DOS Partition
\n ' 06h 16-bit FAT (Partition Larger than 32MB)
\n ' 0Bh 32-bit FAT (Partition Up to 2048GB)
\n ' 0Ch Same as 0BH, but uses LBA1 13h Extensions
\n ' 0Eh Same as 06H, but uses LBA1 13h Extensions
\n ' 0Fh Same as 05H, but uses LBA1 13h Extensions
\n
\n Select Case Sdbuffer(&H1c3)
\n Case &H0B To &H0C : Sdfattype = 4 ' FAT32
\n Case &H04 : Sdfattype = 2 ' FAT16
\n Case &H06 : Sdfattype = 2 ' FAT16
\n Case &H0E : Sdfattype = 2 ' FAT16
\n Case Else : ' My Kingston CL2 4GB SD card suddenly would only report &H72, even after formatting
\n If Sdbuffer(55) = 70 And Sdbuffer(56) = 65 And Sdbuffer(57) = 84 And Sdbuffer(58) = 49 And Sdbuffer(59) = 54 Then
\n Sdfattype = 2 ' FAT16
\n Elseif Sdbuffer(83) = 70 And Sdbuffer(84) = 65 And Sdbuffer(85) = 84 And Sdbuffer(86) = 51 And Sdbuffer(87) = 50 Then
\n Sdfattype = 4 ' FAT32
\n Else
\n Sdstatus = 23 ' Not supported file system
\n End If
\n End Select
\n
\n If Sdstatus = 0 Then
\n
\n If Sdbuffer(&H0c) = 0 And Sdbuffer(&H0d) = 2 Then ' (&H0b-c) Bytes Per Sec
\n
\n Sdsecspercluster = Sdbuffer(&H0e) ' [$0d] Read Secs Per Cluster
\n If Sdsecspercluster > 64 Then
\n Sdstatus = 29 ' Unsupported number of sectors per cluster
\n Else
\n
\n ' Sdtempb represents Sdnumoffats
\n Sdtempb = Sdbuffer(&H11) ' [$10] Read Num of FATs
\n
\n If Sdfattype = 2 Then ' FAT16
\n ' Sdtempd represents Sdsecsperfatl
\n Sdtempdb(1) = Sdbuffer(&H17) ' [$16] Read Secs Per FAT
\n Sdtempdb(2) = Sdbuffer(&H18) ' [$17]
\n Sdtempdb(3) = 0
\n Sdtempdb(4) = 0
\n
\n ' Sdtempw represents Sdmaxrootentriesw
\n Sdtempwb(1) = Sdbuffer(&H12) ' [$11] Read maximum number of root entries (N/A for FAT32)
\n Sdtempwb(2) = Sdbuffer(&H13) ' [$12]
\n Sdsecsinroot = Sdtempw * 32 ' Calculate Sectors in Root Dir
\n Sdsecsinroot = Sdsecsinroot / Sdbytespersecw
\n
\n Else ' FAT32
\n
\n ' Sdfat32rootclusterb(1) = Sdbuffer(45) ' Cluster number for the FAT32 root (normally 2 but could be higher (e.g. in case of bad cluster))
\n ' Sdfat32rootclusterb(2) = Sdbuffer(46)
\n ' Sdfat32rootclusterb(3) = Sdbuffer(47)
\n ' Sdfat32rootclusterb(4) = Sdbuffer(48)
\n
\n Sdtempdb(1) = Sdbuffer(45) ' Cluster number for the FAT32 root (normally 2 but could be higher (e.g. in case of bad cluster))
\n Sdtempdb(2) = Sdbuffer(46)
\n Sdtempdb(3) = Sdbuffer(47)
\n Sdtempdb(4) = Sdbuffer(48)
\n
\n If Sdtempd = 2 Then
\n
\n ' Sdtempd represents Sdsecsperfatl
\n Sdtempdb(1) = Sdbuffer(&H25) ' [$24] Read Secs Per FAT
\n Sdtempdb(2) = Sdbuffer(&H26) ' [$25]
\n Sdtempdb(3) = Sdbuffer(&H27) ' [$26]
\n Sdtempdb(4) = Sdbuffer(&H28) ' [$27]
\n
\n Sdsecsinroot = 0
\n
\n #if Sdusefsinfo = 1
\n Sdfat32fsinfolocationb(1) = Sdbuffer(49) ' Sector number for the FAT32 fsinfo (normally 1)
\n Sdfat32fsinfolocationb(2) = Sdbuffer(50)
\n Sdfat32fsinfolocationw = Sdfat32fsinfolocationw + Sdsectord
\n #endif
\n
\n Else
\n
\n Sdstatus = 21 ' Unsupported FAT32 root cluster number (not 2)
\n
\n End If
\n
\n End If
\n
\n #if Sdusewipe = 1
\n ' First see if BPB_TotSec16 contains size:
\n Sdtotsecsb(1) = Sdbuffer(20) ' Read total number of sectors in the entire partition
\n Sdtotsecsb(2) = Sdbuffer(21)
\n Sdtotsecsb(3) = 0
\n Sdtotsecsb(4) = 0
\n
\n ' If not, look in BPB_TotSec32:
\n If Sdtotsecsd = 0 Then
\n Sdtotsecsb(1) = Sdbuffer(33) ' Read total number of sectors in the entire partition
\n Sdtotsecsb(2) = Sdbuffer(34)
\n Sdtotsecsb(3) = Sdbuffer(35)
\n Sdtotsecsb(4) = Sdbuffer(36)
\n End If
\n #endif
\n
\n ' Sdtempw represents Sdreservedsecsw
\n Sdtempwb(1) = Sdbuffer(&H0f) ' [$0e] Read Num of Reserved Sectors
\n Sdtempwb(2) = Sdbuffer(&H10) ' [$0f]
\n
\n ' Sdsectord represents Sdbootrecordl
\n ' Sdtempw represents Sdreservedsecsw
\n Sdfat1location = Sdsectord + Sdtempw ' Locate FAT1
\n Sdfat2location = Sdfat1location + Sdtempd ' Locate FAT2 (Sdtempd represents Sdsecsperfatl)
\n
\n ' Sdtempb represents Sdnumoffats
\n ' Sdtempd represents Sdsecsperfatl
\n Sdrootdirlocation = Sdtempb * Sdtempd ' Locate FAT16 Root Dir (Sdrootdirlocation is only relevant for FAT<32 and as a basis for the start of the data area)
\n ' Sdrootdirlocation = Sdbootrecordl + Sdrootdirlocation
\n ' Sdrootdirlocation = Sdreservedsecsw + Sdrootdirlocation
\n Sdrootdirlocation = Sdfat1location + Sdrootdirlocation
\n
\n Sddataareastart = Sdrootdirlocation + Sdsecsinroot ' Locate start of data, starts with cluster 2 (where the FAT32 root directory is)
\n
\n End If
\n
\n Else
\n
\n Sdstatus = 35 ' Unsupported sector size (not 512)
\n
\n End If
\n
\n End If
\n
\n End If
\n End If
\n '******************* sdinitfs end *******************
\n '$include "Example_FIND_READ_FILE.bas"
\n '******************* Example_FIND_READ_FILE *************
\n ' If Turn = 3 Then Sdentrynames = "05 " ' Directory entry name, upper case only
\n ' If Turn = 5 Then Sdentrynames = "15 "
\n ' If Turn = 2 Then Sdentrynames = "18 " ' Directory entry name, upper case only
\n ' If Turn = 0 Then Sdentrynames = "VIRUS " ' Directory entry name, upper case only
\n ' If Turn = 4 Then Sdentrynames = "ICE822 "
\n ' If Turn = 1 Then Sdentrynames = "CHO8M22 "
\n
\n Sddirectorymode = 0 ' Find file mode
\nSdclusterd = 0
\nSdsecincluster = Sdsecincluster
\nSdbufferpos = Sdbufferpos
\n
\n'Gosub Sdfindentryindirectory
\n'********* sdfindentryindirectory ***************
\n Sdfindentryindirectory:
\n ' Used to find a file, subdirectory, volume ID, or available directory entry
\n
\n ' Input variables:
\n ' Sdclusterd = the cluster number for the directory in which you want to search (actual cluster or 0 for root directory)
\n ' Sdsecincluster = 1 if you are doing your first search, otherwise the actual Sdsecincluster
\n ' Sdbufferpos = 1 if you are doing your first search, otherwise the actual Sdbufferpos
\n ' Sdentrynames = the file or subdirectory name
\n ' Sddirectorymode 0 = find file, 1 = find subdirectory, 2 = find volume ID, 3 = find available directory entry, 4 find parent directory
\n ' If Sdrwmode = 2 Or Sdrwmode = 4
\n ' Sdreaddestination 0 = Sdbuffer(), 1 = Sdfatbuffer()
\n
\n ' Output variables:
\n ' Sdstatus:
\n ' 28 = An available directory space has been found
\n ' 31 = EOC End OF Cluster chain found (directory)
\n ' 32 = EOD End Of Directory marker found
\n ' 34 = The volume ID has been found
\n ' 47 = Parent directory pointer found
\n ' 48 = File or subdirectory found
\n
\n ' Sddirectorymode = 2:
\n ' Sdclusterd = Next cluster number (where file/subdirectory resides)
\n ' Sdentrynames = The volume ID
\n
\n ' Sddirectorymode <> 2:
\n ' Sddirclusterd = Cluster number for this directory entry
\n ' Sddirsecincluster = Chain start sector number of the current directory cluster, 1 to Sdsecincluster
\n ' Sddirbufferpos = Chain start directory buffer position, 1 to 512
\n ' Sdclusterd = Next cluster number (where file/subdirectory resides)
\n
\n ' 2 = write unbuffered
\n ' 1 = write buffered
\n ' 0 = not writing
\n '#if Sdwmode = 1
\n ' Sdreaddestination = 0 ' Only relevant for buffered writing
\n '#endif
\n
\n ' Special handling of root directory
\n Cls
\n Lcd "Sdfattype " ; Sdfattype
\n If Sdclusterd = 0 Then
\n If Sdfattype = 2 Then ' FAT16 root directory
\n Sdsectord = Sdrootdirlocation
\n Sdsectorend = Sdsecsinroot
\n Else
\n Sdclusterd = Sdfat32rootclusterd ' FAT32 root directory remapped to cluster 2
\n End If
\n End If
\n
\n ' If not in FAT16 root directory, locate the first directory sector
\n ' If Sdclusterd > 0 Then
\n ' Sdsectorend = Sdsecspercluster
\n ' Gosub Sdlocatesector ' Calculate the first sector in Sdclusterd and place in Sdsectord
\n ' End If
\n
\n
\n Do
\n Do ' Loop through this cluster
\n Sdbufferpos = 1
\n
\n Gosub Sddirsectorloop
\n
\n If Sdstatus = 0 Then
\n Incr Sdsectord
\n Sdbufferpos = 1
\n Incr Sdsecincluster
\n End If
\n
\n ' Loop through this cluster until:
\n ' file or subdirectory is found or
\n ' empty directory entry has been found or
\n ' we have scanned all sectors in the cluster without finding the entry
\n Loop Until Sdstatus <> 0 Or Sdsecincluster > Sdsectorend
\n
\n If Sdstatus = 0 Then ' Entry hasn't been found and we have reached the end of the current directory cluster or FAT16 root directory
\n If Sdclusterd = 0 Then
\n Sdstatus = 46 ' We have searched the entire FAT16 root directory but not found what we were looking for
\n Else
\n #if Sdwmode > 0
\n Sdpreviousclusterd = Sdclusterd ' If we are writing, we here want to store the previous cluster number for cluster extension
\n #endif
\n Gosub Sdlocatenextcluster ' Look up the next cluster in the FAT
\n Gosub Sdcheckclusterreference ' Check if it indicates EOC (in that case Sdstatus = 31)
\n If Sdstatus = 0 Then
\n Gosub Sdlocatesector ' Calculate the first sector in the next Sdclusterd and place in Sdsectord
\n Sdsecincluster = 1
\n
\n #if Sdwmode > 0 ' Store directory position if we are using write mode
\n Else ' We have reached the EOC marker, store this directory
\n Sddirclusterd = Sdpreviousclusterd ' Store the directory cluster number in Sddirclusterd
\n Sddirsecincluster = Sdsecincluster ' Chain start sector number of the current directory cluster, 1 to Sdsecincluster
\n Sddirbufferpos = Sdbufferpos ' Chain start directory buffer position, 1 to 512
\n #endif
\n
\n End If
\n End If
\n End If
\n
\n Loop Until Sdstatus <> 0
\n '*************** Sdfindentryindirectory: end **************
\n Cls
\n Locate 1 , 1
\n Lcd " Sd_status=" ; Sdstatus
\n
\nIf Sdstatus = 48 Then ' File found
\n Sdstatus = 0
\n Cls
\n Locate 1 , 1
\n Lcd "found WAV OK " '; Sdentrynames
\n Locate 2 , 1
\n Lcd Sdentrynames
\n
\n
\n
\n 'If Sdfilesized > 0 Then
\n ' Sdsecincluster = 0 ' Set to 0 before the very first call
\n Sdeof = 0
\n Sdbytesread = 0 ' must be set to 0 otherwise oef occur in sub sdreadbyte
\n Read_sound = 0
\n Pointer_sd = 0
\n Timer2 = 73
\n Start Timer2
\n X1 = 0
\n 'Gosub Sdreadbyte
\n While Sdeof < 1
\n ' loop until end of file
\n Sdbufferpos = 513
\n Read_sound = 1
\n 'If Sdbytesread >= Sdfilesized Then
\n 'Sdeof = 1
\n 'Goto Suite
\n 'End If
\n
\n If X1 = 160 Then Gosub Sdreadbyte '185 for begin double buffering
\n
\n
\n Wend
\nSuite:
\n Stop Timer2
\n Read_sound = 0
\n Sdstatus = 9
\n Pwm1a = 0
\nElse ' Handle file not found
\n
\n Sdstr = Str(sdstatus)
\n Locate 2 , 2
\n Lcd "not found" ; "= " ; Sdstr
\n Wait 5
\nEnd If
\n
\n'******************* Example_FIND_READ_FILE end *************
\n
\n ' $include "Example_FIND_READ_DIR_FILE.bas"
\n ' $include "Example_FIND_READ_VOLUME_ID.bas"
\n ' $include "Example_FIND_AVAILABLE_DIR_ENTRY.bas"
\n
\n ' $include "Example_DIRLIST_READ_FILE.bas"
\n ' $include "Example_DIRLIST_READ_FILE_LFN.bas"
\n ' $include "Example_DIRLIST_SCROLL.bas"
\n ' $include "Example_DIRLIST_SCROLL_LFN-test.bas"
\n
\n
\n ' $include "Example_WRITE_FILE.bas"
\n ' $include "Example_APPEND_TO_FILE.bas"
\n ' $include "Example_WRITE_SUBDIRECTORY.bas"
\n
\n ' $include "Example_WIPE.bas"
\n
\nEnd If
\nTurn = Turn + 1 'change music
\nIf Turn > 5 Then Turn = 0
\nGoto Debut '
\nEnd '******************************** end**************************
\n
\n
\n
\n'wwwwwwwwwwwwwwwwwww
\n ' KokkeKat FAT-free SD library code for SDSC, SDHC, and SDXC - INCLUDE at the end of your code
\n' Written by Niclas Arndt, Stockholm, Sweden, 2011.05.06
\n' License terms apply, as stated in the application note
\n
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdcheckr1:
\n ' If Sdresponse(1).1 = 1 Then
\n ' Sdstatus = 11 ' R1 erase reset
\n ' Elseif Sdresponse(1).2 = 1 Then
\n ' Sdstatus = 12 ' R1 illegal command
\n ' Elseif Sdresponse(1).3 = 1 Then
\n ' Sdstatus = 13 ' R1 command CRC error
\n ' Elseif Sdresponse(1).4 = 1 Then
\n ' Sdstatus = 14 ' R1 erase sequence error
\n ' Elseif Sdresponse(1).5 = 1 Then
\n ' Sdstatus = 15 ' R1 address error
\n ' Elseif Sdresponse(1).6 = 1 Then
\n ' Sdstatus = 16 ' R1 parameter error
\n ' Elseif Sdresponse(1).0 = 1 Then
\n ' Sdstatus = 10 ' R1 idle (running initialization)
\n ' End If
\n Return
\n
\n
\n
\n'-------------------------------------------------------------------------------
\n
\nSdcommand1:
\n Spiout Sdcommand , 1
\nReturn
\n
\n'-------------------------------------------------------------------------------
\n
\nSdresponse1:
\n Spiin Sdresponse(1) , 1
\nReturn
\n
\n'-------------------------------------------------------------------------------
\n
\nSdresponse2_5:
\n Spiin Sdresponse(2) , 5
\nReturn
\n
\n'-------------------------------------------------------------------------------
\n
\nSdresponseloop:
\n Sdtempb = 0
\n Do
\n Gosub Sdresponse1 ' Receive the single byte of response
\n Incr Sdtempb
\n Loop Until Sdresponse(1) <> 255 Or Sdtempb = 255
\nReturn
\n
\n'-------------------------------------------------------------------------------
\n'************************ start sdreadsector modified for playing wave ********************
\nSdreadsector: ' Read sector from SD
\n
\n If Sdcardtype <= 2 Then
\n Shift Sdsectord , Left , 9 ' Byte addressing for SDSC cards (shift left 9 = multiply by 512)
\n End If
\n
\n Reset Sd_cs
\n
\n Sdcommand = &HFF ' Clock SD
\n Gosub Sdcommand1
\n
\n Sdcommand = &H51 ' Send CMD17
\n Gosub Sdcommand1
\n Sdcommand = Sdsectorb(4)
\n Gosub Sdcommand1
\n Sdcommand = Sdsectorb(3)
\n Gosub Sdcommand1
\n Sdcommand = Sdsectorb(2)
\n Gosub Sdcommand1
\n Sdcommand = Sdsectorb(1)
\n Gosub Sdcommand1
\n Sdcommand = &HFF
\n Gosub Sdcommand1
\n
\n Sdexpectedresponse = &H00 ' First response after CMD17
\n Gosub Sdseekresponse
\n
\n If Sdcardtype <= 2 Then
\n Shift Sdsectord , Right , 9 ' Byte addressing for SDSC cards (shift right 9 = divide by 512)
\n End If
\n
\n If Sdstatus = 0 Then
\n Sdexpectedresponse = &HFE ' Start token after CMD17
\n Gosub Sdseekresponse
\n If Sdstatus = 0 Then
\n
\n ' 2 = write unbuffered
\n ' 1 = write buffered
\n ' 0 = not writing
\n #if Sdwmode <> 1
\n
\n If Sdbufferpos = 513 And Read_sound = 1 Then ' start only for last 45 byte for buffer reading
\n Do
\n Loop Until X1 = 240
\n For Sdtempw = 1 To 256 ' Read the data block into Sdbuffer
\n Spiin Sdbuffer(sdtempw) , 1
\n
\n X2 = Sdtempw
\n 'X2 = X2 + 1
\n Buffer1(x2) = Sdbuffer(sdtempw) ' store data in 256 byte ram for playing
\n
\n Incr Sdbytesread
\n Next Sdtempw
\n Do
\n Loop Until X1 = 240
\n X2 = 0
\n For Sdtempw = 256 To 512 ' Read the data block into Sdbuffer
\n Spiin Sdbuffer(sdtempw) , 1
\n
\n
\n X2 = X2 + 1
\n Buffer1(x2) = Sdbuffer(sdtempw) ' store data in 256 byte ram for playing
\n
\n Incr Sdbytesread
\n Next Sdtempw
\n
\n
\n
\n
\n
\n Read_sound = 1
\n End If
\n
\n If Pointer_sd = 1 And Read_sound = 0 Then ' start imediatly because one reading allready made
\n Do
\n Loop Until X1 = 240
\n
\n For Sdtempw = 1 To 256 ' Read the data block into Sdbuffer
\n Spiin Sdbuffer(sdtempw) , 1
\n
\n X2 = Sdtempw
\n 'X2 = X2 + 1
\n Buffer1(x2) = Sdbuffer(sdtempw) ' store data in 256 byte ram for playing
\n
\n Incr Sdbytesread
\n Next Sdtempw
\n Do
\n Loop Until X1 = 240
\n X2 = 0
\n For Sdtempw = 256 To 512 ' Read the data block into Sdbuffer
\n Spiin Sdbuffer(sdtempw) , 1
\n
\n
\n X2 = X2 + 1
\n Buffer1(x2) = Sdbuffer(sdtempw) ' store data in 256 byte ram for playing
\n
\n Incr Sdbytesread
\n Next Sdtempw
\n Read_sound = 1
\n End If
\n
\n If Read_sound = 0 And Pointer_sd = 0 Then 'fast read no storage in buffer
\n For Sdtempw = 1 To 512
\n Incr Sdbytesread
\n Spiin Sdbuffer(sdtempw) , 1
\n Next Sdtempw
\n End If
\n
\n
\n #endif
\n
\n #if Sdwmode = 1
\n
\n If Sdreaddestination = 0 Then
\n For Sdtempw = 1 To 512 ' Read the data block into Sdbuffer
\n Spiin Sdbuffer(sdtempw) , 1
\n Next Sdtempw
\n Else
\n For Sdtempw = 1 To 512 ' Read the data block into Sdfatbuffer
\n Spiin Sdfatbuffer(sdtempw) , 1
\n Next Sdtempw
\n End If
\n #endif
\n
\n Gosub Sdresponse1 ' Read dummy CRC to conclude data block
\n Gosub Sdresponse1
\n End If
\n End If
\n
\n Set Sd_cs
\n
\n Sdcommand = &HFF ' Clock SD to complete job
\n Gosub Sdcommand1
\n
\nReturn
\n'************************ end sdreadsector modified for playing wave ********************
\n'-------------------------------------------------------------------------------
\n
\nSdseekresponse: ' Wait for Sdexpectedresponse from SD or timeout
\n Sdtempw = 0
\n Do
\n Gosub Sdresponse1
\n Incr Sdtempw
\n Loop Until Sdresponse(1) = Sdexpectedresponse Or Sdtempw = &HFFFF 'FFFF
\n
\n If Sdresponse(1) <> Sdexpectedresponse Then
\n Sdstatus = 7 ' Timeout
\n End If
\nReturn
\n
\n'-------------------------------------------------------------------------------
\n
\n#if Sdwmode > 0
\n
\n Sdwritesector: ' Write sector to SD
\n
\n If Sdcardtype <= 2 Then
\n Shift Sdsectord , Left , 9 ' Byte addressing for SDSC cards (shift left 9 = multiply by 512)
\n End If
\n
\n Reset Sd_cs
\n
\n Sdcommand = &HFF ' Clock SD to prepare for new command
\n Gosub Sdcommand1
\n
\n Sdcommand = &H58 ' Send CMD24
\n Gosub Sdcommand1
\n Sdcommand = Sdsectorb(4)
\n Gosub Sdcommand1
\n Sdcommand = Sdsectorb(3)
\n Gosub Sdcommand1
\n Sdcommand = Sdsectorb(2)
\n Gosub Sdcommand1
\n Sdcommand = Sdsectorb(1)
\n Gosub Sdcommand1
\n Sdcommand = &HFF
\n Gosub Sdcommand1
\n
\n Sdexpectedresponse = &H00 ' First response after CMD24
\n Gosub Sdseekresponse
\n
\n If Sdcardtype <= 2 Then
\n Shift Sdsectord , Right , 9 ' Byte addressing for SDSC cards (shift right 9 = divide by 512)
\n End If
\n
\n If Sdstatus = 0 Then
\n Sdcommand = &HFE ' Start block token after CMD24
\n Gosub Sdcommand1
\n
\n ' 2 = write unbuffered
\n ' 1 = write buffered
\n ' 0 = not writing
\n #if Sdwmode = 1
\n If Sdwriteorigin = 0 Then ' Write the data block from Sdbuffer
\n For Sdtempw = 1 To 512
\n Spiout Sdbuffer(sdtempw) , 1
\n Next Sdtempw
\n Else ' Write the data block from Sdfatbuffer
\n For Sdtempw = 1 To 512
\n Spiout Sdfatbuffer(sdtempw) , 1
\n Next Sdtempw
\n End If
\n #else
\n For Sdtempw = 1 To 512 ' Write the data block from Sdbuffer
\n Spiout Sdbuffer(sdtempw) , 1
\n Next Sdtempw
\n' Sdtempw = 1
\n' Do
\n' Spiout Sdbuffer(Sdtempw) , 128
\n' Sdtempw = Sdtempw + 128 ' Max 255 bytes per turn
\n' Loop Until Sdtempw = 513
\n #endif
\n
\n Sdcommand = &HFF ' Write dummy CRC to conclude data block
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n
\n Sdtempw = 0
\n Do ' Wait for and receive data response token
\n Gosub Sdresponse1
\n Incr Sdtempw
\n Loop Until Sdresponse(1) <> &HFF Or Sdtempw = 512
\n
\n Sdtempb = Sdresponse(1) And &H0F
\n Select Case Sdtempb
\n Case &H05 : Sdstatus = 0 ' Data accepted
\n Case &H0B : Sdstatus = 41 ' Data rejected due to a CRC error
\n Case &H0D : Sdstatus = 42 ' Data rejected due to a Write Error
\n End Select
\n
\n If Sdstatus = 0 Then ' Wait until card is no longer busy
\n Sdexpectedresponse = &HFF
\n Gosub Sdseekresponse
\n End If
\n
\n End If
\n
\n Sdcommand = &HFF ' Clock SD to complete job
\n Gosub Sdcommand1
\n
\n Set Sd_cs
\n
\n Sdcommand = &HFF ' Clock SD to complete job
\n Gosub Sdcommand1
\n
\n Return
\n
\n#endif
\n
\n
\n'-------------------------------------------------------------------------------
\n
\n#if Sdfsactive = 1
\n
\n Sdinitfs:
\n
\n
\n
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdlocatesector:
\n
\n ' Input variable:
\n ' Sdclusterd = current cluster
\n
\n ' Output variable:
\n ' Sdsectord = the absolute sector number for this cluster
\n
\n Sdsectord = Sdclusterd - 2
\n Sdsectord = Sdsectord * Sdsecspercluster
\n Sdsectord = Sdsectord + Sddataareastart
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdlocatenextcluster:
\n
\n ' Input variable:
\n ' Sdclusterd = current cluster
\n
\n ' Output variable:
\n ' Sdclusterd = next cluster
\n
\n Gosub Sdcalculatefat1sector
\n Read_sound = 0 ' dont stor reading byte in the music buffer
\n
\n Gosub Sdreadsector ' Read the FAT sector
\n If Sdstatus = 0 Then
\n Sdbufferpos = Sdbufferpos - 1
\n Sdtempw = 0
\n Do
\n Incr Sdtempw
\n Incr Sdbufferpos
\n Sdclusterb(sdtempw) = Sdbuffer(sdbufferpos)
\n Loop Until Sdtempw = Sdfattype
\n End If
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdcalculatefat1sector:
\n
\n ' Input variable:
\n ' Sdclusterd = current cluster
\n
\n ' Output variables:
\n ' Sdsectord = absolute FAT1 sector number
\n ' Sdbufferpos = buffer pos in this sector
\n
\n Sdtempd = Sdclusterd * Sdfattype ' Offset in bytes from sdfat1location (Sdfattype = 2 for FAT16 and 4 for FAT32)
\n Sdsectord = Sdtempd \ Sdbytespersecw ' Offset in sectors from sdfat1location
\n Sdtempd = Sdtempd Mod Sdbytespersecw ' Byte position in the resulting sector (1 too low!)
\n Sdbufferpos = Sdtempd + 1
\n Sdsectord = Sdsectord + Sdfat1location ' FAT sector for the current cluster
\n
\n Return
\n
\n#endif
\n
\n
\n'===============================================================================
\n
\n
\n#if Sdrmode = 1 And Sdfsactive = 1
\n
\n Sdreadbyte:
\n ' Used to read a single byte from the current file, as located by Gosub Sdfindentryindirectory or Gosub Sddirlist
\n
\n ' Before calling, make sure that Sdfilesized > 0, Sdstatus = 0, and Sdeof = 0
\n
\n ' Input variables:
\n ' Sdclusterd = current file cluster
\n ' Sdsecincluster = sector number in this cluster, set to 0 before the very first call
\n ' Sdbufferpos = buffer pos in this sector
\n ' Sdsectord = absolute sector number
\n
\n ' Output variables:
\n ' Sdbyterw = the read byte
\n ' Sdbytesread = read byte counter
\n ' Sdeof 1 = End Of File found, else 0
\n ' Sdstatus
\n
\n If Sdsecincluster = 0 Then ' Very first call
\n
\n #if Sdusedirlist = 1
\n Sdfilesizeb(1) = Sddirlistdirentry(29) ' Read file size in bytes
\n Sdfilesizeb(2) = Sddirlistdirentry(30)
\n Sdfilesizeb(3) = Sddirlistdirentry(31)
\n Sdfilesizeb(4) = Sddirlistdirentry(32)
\n
\n Sdclusterb(1) = Sddirlistdirentry(27) ' Cluster number for the subdirectory we are about to enter
\n Sdclusterb(2) = Sddirlistdirentry(28)
\n Sdclusterb(3) = Sddirlistdirentry(21)
\n Sdclusterb(4) = Sddirlistdirentry(22)
\n #endif
\n
\n Gosub Sdlocatesector ' Read the first sector of the cluster where the file starts
\n Gosub Sdreadsector
\n If Sdstatus = 0 Then
\n Sdsecincluster = 1 ' Initialize pointers and byte counter
\n Sdbufferpos = 1
\n Sdbytesread = 0
\n Sdeof = 0
\n End If
\n
\n End If
\n
\n If Sdbufferpos > Sdbytespersecw Then ' Have we passed the end of the sector?
\n Incr Sdsecincluster
\n If Sdsecincluster > Sdsecspercluster Then ' Have we passed the last sector of this cluster?
\n Gosub Sdlocatenextcluster ' Locate next cluster
\n Gosub Sdcheckclusterreference ' Check if it indicates EOC (in that case Sdstatus = 31)
\n If Sdstatus = 0 Then ' EOF has not been reached
\n Gosub Sdlocatesector ' Locate the sector start of the new cluster
\n
\n Pointer_sd = 1
\n
\n Gosub Sdreadsector
\n Pointer_sd = 0
\n Sdsecincluster = 1
\n End If
\n Else
\n Incr Sdsectord
\n Gosub Sdreadsector
\n End If
\n Sdbufferpos = 1
\n End If
\n
\n If Sdstatus = 0 Then
\n Sdbyterw = Sdbuffer(sdbufferpos)
\n Incr Sdbufferpos
\n Incr Sdbytesread
\n If Sdbytesread >= Sdfilesized Then
\n Sdeof = 1
\n End If
\n Else
\n Sdeof = 1
\n End If
\n
\n Return
\n
\n#endif
\n
\n'===============================================================================
\n
\n#if Sdusefind = 1
\n
\n
\n 'Return
\n
\n
\n '-------------------------------------------------------------------------------
\n
\n Sddirsectorloop:
\n ' Called from Sdfindentryindirectory
\n
\n ' Input variables:
\n ' Sdsectord = absolute directory sector number
\n ' Sdbufferpos = 1 if you are doing your first search, otherwise the actual Sdbufferpos
\n ' Sddirectorymode
\n ' 0 = find file
\n ' 1 = find subdirectory
\n ' 2 = find volume ID
\n ' 3 = find available directory entry
\n ' 4 = find parent directory
\n ' 5 = return entire entry unless EOD (only if enabled by Sdusefindstoreentry = 1)
\n
\n ' Output variables:
\n ' Sdstatus:
\n ' 28 = An available directory space has been found
\n ' 32 = EOD End Of Directory marker found
\n ' 34 = The volume ID has been found
\n ' 47 = Parent directory pointer found
\n ' 48 = File or subdirectory found
\n
\n ' Sddirectorymode = 2:
\n ' Sdclusterd = Next cluster number (where file/subdirectory resides)
\n ' Sdentrynames = The volume ID
\n
\n ' Sddirectorymode <> 2:
\n ' Sddirclusterd = Cluster number for this directory entry
\n ' Sddirsecincluster = Chain start sector number of the current directory cluster, 1 to Sdsecincluster
\n ' Sddirbufferpos = Chain start directory buffer position, 1 to 512
\n ' Sdclusterd = Next cluster number (where file/subdirectory resides)
\n
\n Gosub Sdreadsector ' Read Sdsectord to buffer
\n If Sdstatus = 0 Then
\n Do
\n If Sdbuffer(sdbufferpos) = &H00 Then
\n Sdstatus = 32 ' EOD End Of Directory marker found
\n Else
\n
\n #if Sdusefind = 1 And Sdusefindstoreentry = 1
\n If Sddirectorymode = 5 Then ' Store the entire directory entry in Sdfinddirentry()
\n Sdtempw = Sdbufferpos
\n For Sdtempb = 1 To 32
\n Sdfinddirentry(sdtempb) = Sdbuffer(sdtempw)
\n Incr Sdtempw
\n Next Sdtempb
\n Else
\n #endif
\n
\n Sdtempw = Sdbufferpos + 11
\n Sdtempb = Sdbuffer(sdtempw) Or &B11110000
\n If Sdtempb <> &HFF Then ' Not Long FileName entry
\n Select Case Sddirectorymode
\n Case 0 To 1: ' Find file or find subdirectory
\n Sdtempb = 1
\n Sdtempw = Sdbufferpos
\n While Sdbuffer(sdtempw) = Sdentrynameb(sdtempb) And Sdtempb < 12
\n Incr Sdtempb
\n Incr Sdtempw
\n Wend
\n If Sdtempb = 12 Then
\n Sdstatus = 48 ' File or subdirectory found
\n End If
\n Case 2: ' Find volume ID
\n If Sdbuffer(sdtempw).3 = 1 Then
\n Sdstatus = 34 ' Volume ID found
\n Sdtempb = 1
\n Sdtempw = Sdbufferpos
\n While Sdtempb < 12
\n Sdentrynameb(sdtempb) = Sdbuffer(sdtempw)
\n Incr Sdtempb
\n Incr Sdtempw
\n Wend
\n End If
\n
\n #if Sdwmode > 0 ' Find available directory entry is only relevant if we are using write mode
\n Case 3:
\n If Sdbuffer(sdbufferpos) = &HE5 Then
\n Sdstatus = 28 ' Available (previously erased) directory entry found
\n End If
\n #endif
\n
\n Case 4: ' Find parent directory cluster
\n Sdtempw = Sdbufferpos + 1
\n If Sdbuffer(sdbufferpos) = &H2E And Sdbuffer(sdtempw) = &H2E Then
\n Sdstatus = 47 ' Parent directory pointer found
\n End If
\n End Select
\n End If
\n End If
\n If Sdstatus = 0 Then
\n Sdbufferpos = Sdbufferpos + 32 ' Matching entry not found - point to the next entry
\n Else
\n
\n If Sddirectorymode <> 2 Then ' Point to the cluster where the file/subdirectory/parent directory/available directory entry resides
\n
\n #if Sdwmode > 0 ' Store directory position if we are using write mode
\n Sddirclusterd = Sdclusterd ' Store the directory cluster number in Sddirclusterd
\n Sddirsecincluster = Sdsecincluster ' Chain start sector number of the current directory cluster, 1 to Sdsecincluster
\n Sddirbufferpos = Sdbufferpos ' Chain start directory buffer position, 1 to 512
\n #endif
\n
\n Gosub Sdgetclusterandsize ' Place cluster number in Sdclusterd and filesize in Sdfilesized
\n
\n End If
\n End If
\n
\n #if Sdusefind = 1 And Sdusefindstoreentry = 1
\n End If
\n #endif
\n
\n Loop Until Sdstatus <> 0 Or Sdbufferpos > Sdbytespersecw
\n
\n End If
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdcheckclusterreference: ' Check if it indicates EOC (>=&HFFF8 or >=&H0FFFFFF8)
\n If Sdfattype = 2 Then ' FAT16
\n Sdclusterb(3) = 0
\n Sdclusterb(4) = 0
\n If Sdclusterd > &HFFF7 Then
\n Sdstatus = 31 ' EOC End OF Cluster chain found
\n End If
\n Elseif Sdfattype = 4 Then ' FAT32
\n Sdclusterb(4) = Sdclusterb(4) And &B00001111
\n If Sdclusterd > &H0FFFFFF7 Then
\n Sdstatus = 31 ' EOC End OF Cluster chain found
\n End If
\n End If
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdgetclusterandsize:
\n
\n 'If Sdfattype = 4 Then ' FAT32
\n ' Sdtempw = Sdbufferpos + 20
\n ' Sdclusterb(3) = Sdbuffer(sdtempw) ' 21 File/subdirectory cluster number
\n ' Incr Sdtempw
\n ' Sdclusterb(4) = Sdbuffer(sdtempw) ' 22
\n ' Sdtempw = Sdtempw + 5
\n 'Else ' FAT16
\n Sdclusterb(3) = 0
\n Sdclusterb(4) = 0
\n Sdtempw = Sdbufferpos + 26
\n 'End If
\n
\n Sdclusterb(1) = Sdbuffer(sdtempw) ' 27
\n Incr Sdtempw
\n Sdclusterb(2) = Sdbuffer(sdtempw) ' 28
\n
\n Incr Sdtempw
\n Sdfilesizeb(1) = Sdbuffer(sdtempw) ' 29 File size in bytes
\n Incr Sdtempw
\n Sdfilesizeb(2) = Sdbuffer(sdtempw) ' 30
\n Incr Sdtempw
\n Sdfilesizeb(3) = Sdbuffer(sdtempw) ' 31
\n Incr Sdtempw
\n Sdfilesizeb(4) = Sdbuffer(sdtempw) ' 32
\n
\n Return
\n
\n#endif
\n
\n'===============================================================================
\n
\n' 2 = write unbuffered
\n' 1 = write buffered
\n' 0 = not writing
\n#if Sdwmode > 0 And Sdfsactive = 1
\n
\n Sdcreatefileordir:
\n ' Used as the first of three steps when creating a new file or the only step when creating a new subdirectory
\n ' (Sdwritebyte and Sdclosefile are the subsequent two)
\n
\n ' Find free FAT entry, find free directory entry, and save the directory entry back to the SD card
\n
\n ' Input variables:
\n ' Sdentrynames = the 8.3 filename
\n ' Sdcreatemode 0 = file, 1 = subdirectory
\n ' Sdstartdirclusterd = the directory cluster number (in which the file or subdirectory should be created). Set to 0 for root directory.
\n ' Sdyear = the year
\n ' Sdmonth = the month
\n ' Sdday = the day
\n ' Sdhours = the hours
\n ' Sdminutes = the minutes
\n ' Sdseconds = the seconds
\n ' Sdmseconds = the milliseconds
\n
\n ' If Sdmaintainfsinfo = 1
\n ' Sdfsinfofreeclustersd = the number of free clusters
\n ' Sdfsinfonextfreeclusterd = the next unused cluster (typically not the first free re-usable cluster)
\n
\n ' Output variables:
\n ' Sdpartitionfull = 1 if the partition is full (no more free FAT entries)
\n ' Sdfatsectornum = the FAT sector number
\n ' Sdfatbufferpos = the position in this sector
\n ' Sddirclusterd = the directory cluster
\n ' Sddirsecincluster = the sector in this cluster
\n ' Sddirbufferpos = the position in this sector
\n ' Sdwclusterd = the cluster number we are writing to
\n ' Sdwsecincluster = the sector in this cluster (1)
\n ' Sdwbufferpos = the position in this sector (0) - please notice!
\n ' Sdwfilesized = the file size (0)
\n
\n ' If Sdmaintainfsinfo = 1
\n ' Sdfsinfofreeclustersd = the number of free clusters
\n ' Sdfsinfonextfreeclusterd = the next unused cluster (typically not the first free re-usable cluster)
\n
\n ' Find the first available directory entry in the specified directory (cluster) and store it in Sddirclusterd, Sddirsecincluster, and Sdirbufferpos
\n Sdclusterd = Sdstartdirclusterd
\n Sdsecincluster = 1
\n Sdbufferpos = 1
\n
\n #if Sdusedirlist = 1
\n Sddirlistarraycounter = 0
\n Sddirlistdirection = 0
\n Do
\n Sdstatus = 0
\n Gosub Sddirlist
\n Loop Until Sdstatus = 28 Or Sdstatus = 32 Or Sddirlistendpoint = 1 ' Empty entry found or EOD marker found or EOD reached
\n
\n ' Store directory position for this directory entry
\n Sddirclusterd = Sdclusterd ' Chain start directory cluster number
\n Sddirsecincluster = Sdsecincluster ' Sector number in cluster
\n Sddirbufferpos = Sdbufferpos ' Buffer position in sector
\n
\n If Sddirlistendpoint = 1 And Sddirclusterd <> 0 Then ' EOD found and not in FAT16 root
\n #else
\n #if Sdusefind = 1
\n Sddirectorymode = 3 ' Find available directory entry
\n Gosub Sdfindentryindirectory
\n
\n If Sdstatus = 31 Then ' EOC End OF Cluster chain found (directory) - we must first extend the cluster (if not FAT16 root)
\n #endif
\n #endif
\n
\n Sdstatus = 0
\n
\n ' Extend directory with additional cluster
\n Sdsectord = Sdfat1location ' Find free FAT1 entry and store position in Sdfatsectornum, and Sdfatbufferpos plus Sdfatclusterd
\n Sdbufferpos = 1
\n Gosub Sdfindfreefat
\n
\n If Sdstatus = 0 Then
\n Sdclusterd = Sddirclusterd ' Read the FAT entry for the directory cluster that we are about to extend
\n Gosub Sdcalculatefat1sector
\n Gosub Sdreadsector
\n
\n If Sdstatus = 0 Then ' Save the updated FAT sector holding the now extended directory cluster
\n Sdtempw = Sdbufferpos
\n Sdbuffer(sdtempw) = Sdfatclusterb(1)
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sdfatclusterb(2)
\n If Sdfattype = 4 Then
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sdfatclusterb(3)
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sdfatclusterb(4)
\n End If
\n #if Sdwmode = 1
\n Sdwriteorigin = 0
\n #endif
\n Gosub Sdwritesector
\n If Sdstatus = 0 Then
\n Sdsectord = Sdfat1location - Sdsectord
\n Sdsectord = Sdsectord + Sdfat2location
\n Gosub Sdwritesector
\n If Sdstatus = 0 Then
\n
\n Sdclusterd = &H0FFFFFFF ' Save EOC marker to the FAT entry in Sdfatclusterd
\n Gosub Sdsavefatsec
\n If Sdstatus = 0 Then
\n Sdclusterd = Sdfatclusterd ' Empty the extended directory cluster
\n Gosub Sdwclearcluster
\n If Sdstatus = 0 Then
\n Decr Sdsectord
\n Gosub Sdwritesector
\n If Sdstatus = 0 Then
\n
\n #if Sdusefsinfo = 1
\n Gosub Sdupdatefsinfo ' Update the fsinfo variables
\n #endif
\n
\n ' Store directory position for this directory entry
\n Sddirclusterd = Sdfatclusterd ' Directory cluster number
\n Sddirsecincluster = 1 ' Sector number in cluster
\n Sddirbufferpos = 1 ' Buffer position in sector
\n Gosub Sdlocatesector
\n Sdstatus = 32
\n End If
\n End If
\n End If
\n End If
\n End If
\n End If
\n End If
\n Else
\n Sdfatsectornum = Sdfat1location
\n Sdfatbufferpos = 1
\n End If
\n
\n ' An available (previously erased) directory entry or EOD End Of Directory marker found
\n ' Sddirclusterd, Sddirsecincluster, and Sddirbufferpos now point to this directory entry
\n If Sdstatus = 28 Or Sdstatus = 32 Then ' Free directory entry found
\n Sdstatus = 0 ' Remap Sdstatus
\n
\n ' Find free FAT1 entry and store position in Sdfatsectornum, and Sdfatbufferpos plus Sdfatclusterd
\n Sdsectord = Sdfatsectornum ' Continue looking in the same FAT sector
\n Sdbufferpos = Sdfatbufferpos
\n Gosub Sdfindfreefat
\n If Sdstatus = 0 Then
\n
\n Gosub Sdlocatedirsector ' Point to the available directory entry again
\n '*************ajout***********
\n ' sdsector=sdsector+sddirsecincluster
\n ' decr sdsector
\n '*********** fin ajout *******
\n
\n #if Sdwmode = 1
\n Sdreaddestination = 0
\n #endif
\n Gosub Sdreadsector
\n If Sdstatus = 0 Then
\n
\n #if Sdusefsinfo = 1
\n Gosub Sdupdatefsinfo ' Update the fsinfo variables
\n #endif
\n
\n ' Store all information in this new directory entry, except file size, that will be updated at the end in a second read+write to this directory sector
\n ' Sdentrynames set before calling Sdcreatefileordir
\n Sdclusterd = Sdfatclusterd
\n Sdwfilesized = 0
\n Sdbufferpos = Sddirbufferpos
\n
\n Gosub Sdstoredirentry ' Sdcreatemode set before calling Sdcreatefileordir
\n #if Sdwmode = 1
\n Sdwriteorigin = 0 ' Write from Sdbuffer
\n #endif
\n
\n Gosub Sdwritesector ' Write the updated directory sector back to the SD card
\n
\n End If
\n
\n If Sdcreatemode = 1 And Sdstatus = 0 Then ' Create subdirectory ., .., (and EOD) entries in the new directory cluster
\n
\n Sdclusterd = Sdfatclusterd ' Calculate the absolute sector number for the free cluster and write the last (sdsecspercluster - 1) sectors
\n Gosub Sdwclearcluster
\n
\n If Sdstatus = 0 Then
\n
\n Sdentrynames = Space(11) ' First clean out Sdentrynames
\n Sdentrynameb(1) = &H2E ' Store the subdirectory's starting cluster number in the . directory entry
\n Sdclusterd = Sdfatclusterd
\n Sdwfilesized = 0
\n Sdbufferpos = 1
\n Gosub Sdstoredirentry
\n
\n Sdentrynameb(2) = &H2E ' Store the parent directory's starting cluster number in the .. directory entry
\n Sdclusterd = Sdstartdirclusterd
\n Sdbufferpos = 33
\n Gosub Sdstoredirentry
\n Decr Sdsectord ' Finally write the first sector
\n Gosub Sdwritesector
\n
\n If Sdstatus = 0 Then
\n Sdclusterd = &H0FFFFFFF ' Save EOC marker to the FAT sector in Sdfatclusterd
\n Gosub Sdsavefatsec
\n End If
\n End If
\n End If
\n End If
\n End If
\n Sdclosefile = 0
\n
\n If Sdstatus = 44 Then ' End of FAT and no free entry found (partition full)
\n Sdpartitionfull = 1 ' The partition is full (no more free FAT entries)
\n Sdstatus = 0
\n End If
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n #if Sduseappend = 1
\n
\n Sdpreparetoappend:
\n ' Used to append to a pre-existing file
\n
\n ' Input variables:
\n ' Sdentrynames = the 8.3 filename
\n ' Sdyear = the year
\n ' Sdmonth = the month
\n ' Sdday = the day
\n ' Sdhours = the hours
\n ' Sdminutes = the minutes
\n ' Sdseconds = the seconds
\n ' Sdstartdirclusterd = the first cluster of this (sub-)directory
\n ' Sdfsinfofreeclustersd = the number of free clusters
\n ' Sdfsinfonextfreeclusterd = the next unused cluster (typically not the first free re-usable cluster)
\n
\n ' Output variables:
\n ' Sdwclusterd = the cluster number we are writing to
\n ' Sdwsecincluster = the sector in this cluster
\n ' Sdwbufferpos = the position in this sector
\n ' Sdwfilesized = the file size
\n ' Sdfatsectornum = the FAT sector number
\n ' Sdfatbufferpos = the position in this sector
\n ' Sddirclusterd = the directory cluster
\n ' Sddirsecincluster = the sector in this cluster
\n ' Sddirbufferpos = the position in this sector
\n ' Sdfsinfofreeclustersd = the number of free clusters
\n ' Sdfsinfonextfreeclusterd = the next unused cluster (typically not the first free re-usable cluster)
\n
\n ' Sddirclusterd, Sddirsecincluster, and Sddirbufferpos point to this directory entry
\n ' Sdwclusterd, Sdwsecincluster, and Sdwbufferpos point to the last byte of the file
\n ' Sdfatclusterd, Sdfatsectornum, and Sdfatbufferpos point to the last fat entry(cluster number)
\n
\n
\n ' Find the file
\n Sdclusterd = Sdstartdirclusterd
\n Sdsecincluster = 1
\n Sdbufferpos = 1
\n
\n #if Sdusedirlist = 1
\n Sdappendfound = 0
\n Sddirlistarraycounter = 0
\n Sddirlistdirection = 0 ' Loop through this directory forward
\n Do
\n Do
\n Sdstatus = 0
\n Gosub Sddirlist
\n Loop Until Sdstatus = 26 Or Sdstatus = 32 Or Sddirlistendpoint = 1
\n If Sdstatus = 26 Then ' Look for a file named Sdentrynames
\n Sdappendcontinue = 1
\n Sdtempb = 1
\n Do
\n If Sddirlistdirentry(sdtempb) <> Sdentrynameb(sdtempb) Then
\n Sdappendcontinue = 0
\n End If
\n Incr Sdtempb
\n Loop Until Sdappendcontinue = 0 Or Sdtempb = 12
\n If Sdappendcontinue = 1 Then
\n Sdappendfound = 1
\n End If
\n End If
\n Loop Until Sdappendfound = 1 Or Sdstatus = 32 Or Sddirlistendpoint = 1
\n
\n If Sdappendfound = 1 Then
\n Sdstatus = 0
\n
\n Sddirclusterd = Sdclusterd ' Store this directory entry position
\n Sddirsecincluster = Sdsecincluster
\n Sddirbufferpos = Sdbufferpos
\n
\n Sdwfilesizeb(1) = Sddirlistdirentry(29) ' Store original filesize in Sdwfilesized
\n Sdwfilesizeb(2) = Sddirlistdirentry(30)
\n Sdwfilesizeb(3) = Sddirlistdirentry(31)
\n Sdwfilesizeb(4) = Sddirlistdirentry(32)
\n
\n Sdwclusterb(1) = Sddirlistdirentry(27) ' Store the file's starting cluster number in the new directory entry
\n Sdwclusterb(2) = Sddirlistdirentry(28)
\n Sdwclusterb(3) = Sddirlistdirentry(21)
\n Sdwclusterb(4) = Sddirlistdirentry(22)
\n
\n Sdclusterd = Sdwclusterd
\n
\n #else
\n #if Sdusefind = 1
\n
\n Sddirectorymode = 0 ' Find file
\n Gosub Sdfindentryindirectory
\n If Sdstatus = 48 Then ' File found
\n Sdstatus = 0 ' Sddirclusterd, Sddirsecincluster, and Sddirbufferpos now point to this directory entry
\n
\n Gosub Sdgetclusterandsize ' Place file's starting cluster number in Sdwclusterd and original filesize in Sdwfilesized
\n Sdwclusterd = Sdclusterd
\n Sdwfilesized = Sdfilesized
\n
\n #endif
\n #endif
\n
\n ' Loop through the FAT1 chain until EOC is found
\n Do
\n Sdfatclusterd = Sdclusterd ' Store the last known cluster number
\n Gosub Sdlocatenextcluster ' Look up the next cluster number
\n Gosub Sdcheckclusterreference ' Check if it indicates EOC (in that case Sdstatus = 31)
\n
\n Loop Until Sdstatus <> 0
\n
\n If Sdstatus = 31 Then ' Unless bad cluster found (Assume the original file size is correct)
\n
\n Sdstatus = 0
\n
\n Sdwclusterd = Sdfatclusterd ' Store the file's last cluster number
\n
\n Sdtempd = Sdwfilesized Mod Sdbytespersecw
\n
\n 'Sdwbufferposb(1) = Sdtempdb(1) ' Buffer position in the last sector
\n 'Sdwbufferposb(2) = Sdtempdb(2)
\n Sdwbufferpos = Sdtempd
\n
\n Sdtempd = Sdwfilesized \ Sdbytespersecw ' Number of entire sectors
\n Sdtempd = Sdtempd Mod Sdsecspercluster
\n Sdwsecincluster = Sdtempdb(1) + 1 ' Sector number in the last cluster
\n
\n Sdclusterd = Sdwclusterd ' Calculate the FAT1 sector number and position for this cluster
\n Gosub Sdcalculatefat1sector
\n Sdfatsectornum = Sdsectord ' Store position
\n Sdfatbufferpos = Sdbufferpos
\n
\n #if Sdwmode = 1
\n For Sdtempw = 1 To 512 ' Copy this FAT sector data into Sdfat1buffer
\n Sdfatbuffer(sdtempw) = Sdbuffer(sdtempw)
\n Next Sdtempw
\n #endif
\n
\n Gosub Sdlocatedirsector ' Update the directory sector with the new write and access DateTime
\n #if Sdwmode = 1
\n Sdreaddestination = 0
\n #endif
\n Gosub Sdreadsector
\n If Sdstatus = 0 Then
\n
\n Gosub Sdpreparedatetime ' Calculate and store date and time in the directory entry
\n Sdtempw = Sddirbufferpos + 18
\n Gosub Sdstore19_26
\n
\n #if Sdwmode = 1
\n Sdwriteorigin = 0
\n #endif
\n Gosub Sdwritesector
\n
\n If Sdstatus = 0 Then ' Read the file's last sector into Sdbuffer()
\n Sdclusterd = Sdwclusterd
\n Gosub Sdlocatesector
\n Sdsectord = Sdsectord + Sdwsecincluster
\n Decr Sdsectord
\n Sdstatus = 0
\n Gosub Sdreadsector
\n End If
\n End If
\n
\n End If
\n
\n End If
\n
\n Return
\n
\n #endif
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdwritebyte:
\n ' Used to write a byte to an open file
\n ' Always make sure that Sdclosefile = 0 before writing
\n
\n ' Input variables:
\n ' Sdclosefile must be 0 - otherwise the file should be closed
\n ' Sdwclusterd = the cluster number we are writing to (initially set by Sdcreatefileordir or Sdappendfile - touch only when writing to > 1 file)
\n ' Sdwsecincluster = the sector in this cluster (initially set by Sdcreatefileordir or Sdappendfile - touch only when writing to > 1 file)
\n ' Sdwbufferpos = the position in this sector (initially set by Sdcreatefileordir or Sdappendfile - touch only when writing to > 1 file)
\n ' Sdwfilesized = the file size (initially set by Sdcreatefileordir or Sdappendfile - touch only when writing to > 1 file)
\n ' Sdfatsectornum = the FAT sector number (initially set by Sdcreatefileordir or Sdappendfile - touch only when writing to > 1 file)
\n ' Sdfatbufferpos = the position in this sector (initially set by Sdcreatefileordir or Sdappendfile - touch only when writing to > 1 file)
\n ' Sdbuffer() (touch only when writing to > 1 file)
\n ' Sdbyterw = the data byte we are about to write
\n
\n ' Output variables:
\n ' Sdwclusterd = the cluster number we are writing to
\n ' Sdwsecincluster = the sector in this cluster
\n ' Sdwbufferpos = the position in this sector
\n ' Sdwfilesized = the file size
\n ' Sdfatsectornum = the FAT sector number
\n ' Sdfatbufferpos = the position in this sector
\n ' Sdbuffer()
\n ' Sdpartitionfull = 1 if the partition is full (there are no more free FAT entries)
\n ' Sdclosefile = 1 if the file should be closed after the return from this gosub
\n
\n ' Returned statuses:
\n ' Sdstatus = 0 Successful
\n ' Sdstatus = 7 Timeout
\n ' Sdstatus = 41 Data rejected due to a CRC error
\n ' Sdstatus = 42 Data rejected due to a Write Error
\n ' Sdstatus = 43 Free FAT entry found
\n ' Sdstatus = 44 The partition is full - store FAT EOC marker
\n
\n Incr Sdwbufferpos ' Start by pointing to the next byte
\n If Sdwbufferpos > Sdbytespersecw Then ' After saving the last byte in a sector, save the sector to the SD card
\n Sdclusterd = Sdwclusterd ' Calculate the absolute sector number for this sector
\n Gosub Sdlocatesector
\n Sdsectord = Sdsectord + Sdwsecincluster
\n Decr Sdsectord
\n #if Sdwmode = 1
\n Sdwriteorigin = 0 ' Save sector from Sdbuffer to SD card
\n #endif
\n Gosub Sdwritesector
\n Sdsavedatasector = 0
\n Incr Sdwsecincluster
\n
\n If Sdwsecincluster > Sdsecspercluster Then ' After saving the last sector in the current cluster, look up the next cluster
\n
\n Sdsectord = Sdfatsectornum ' Point to the same FAT sector
\n Sdbufferpos = Sdfatbufferpos + Sdfattype ' Point to the next FAT position
\n
\n #if Sdwmode = 1
\n If Sdbufferpos < Sdbytespersecw Then ' Search for a free FAT entry in the current sector
\n Sdfatcontinue = 1
\n Do
\n Sdtempw = Sdbufferpos ' Look for &H0000 (FAT16) or &H00000000 (FAT32)
\n If Sdfatbuffer(sdtempw) = 0 Then ' Byte 1
\n Incr Sdtempw
\n If Sdfatbuffer(sdtempw) = 0 Then ' Byte 2
\n If Sdfattype = 2 Then ' FAT16
\n Sdstatus = 43 ' Free FAT entry found
\n Sdfatcontinue = 0
\n Else ' FAT32
\n Incr Sdtempw
\n If Sdfatbuffer(sdtempw) = 0 Then ' Byte 3
\n Incr Sdtempw
\n Sdtempb = Sdfatbuffer(sdtempw) And &B00001111
\n If Sdtempb = 0 Then ' Byte 4
\n Sdstatus = 43 ' Free FAT entry found
\n Sdfatcontinue = 0
\n End If
\n End If
\n End If
\n End If
\n End If
\n If Sdfatcontinue = 1 Then
\n Sdbufferpos = Sdbufferpos + Sdfattype
\n End If
\n Loop Until Sdfatcontinue = 0 Or Sdbufferpos > Sdbytespersecw
\n
\n If Sdstatus = 43 Then ' New free FAT entry found in the same FAT sector
\n Gosub Sdcalculatefatentrycluster ' Calculate cluster number
\n Sdtempw = Sdfatbufferpos
\n For Sdtempb = 1 To Sdfattype ' Update this FAT entry with a pointer to the next cluster
\n Sdfatbuffer(sdtempw) = Sdclusterb(sdtempb)
\n Incr Sdtempw
\n Next Sdtempb
\n Sdwclusterd = Sdclusterd ' Update the write cluster pointer
\n Sdwsecincluster = 1 ' Reset write sector number (Sdwbufferpos is reset after return)
\n Sdfatbufferpos = Sdbufferpos ' Update the FAT buffer pointer
\n End If
\n End If
\n
\n If Sdstatus <> 43 Then ' If none is found in the current FAT sector, loop through the next sector(s)
\n Sdbufferpos = 1
\n Sdsectord = Sdfatsectornum + 1 ' Point to the next FAT sector
\n If Sdsectord < Sdfat2location Then
\n Do
\n Gosub Sdfindfreefatentry ' Sdsectord and Sdbufferpos point to the next free FAT
\n Loop Until Sdstatus <> 0
\n
\n If Sdstatus = 43 Then ' New free FAT entry found in another FAT sector
\n Sdstatus = 0
\n Sdtempd = Sdsectord ' Temporarily store the FAT sector number with the current empty entry
\n Gosub Sdcalculatefatentrycluster ' Calculate cluster number into Sdclusterd
\n Gosub Sdsavefatsec ' Store Sdclusterd at Sdfatsectornum & Sdfatbufferpos and save Sdfatbuffer() back to the card
\n If Sdstatus = 0 Then
\n Sdwclusterd = Sdclusterd ' Update the write cluster pointer
\n Sdwsecincluster = 1 ' Reset write sector number (Sdwbufferpos is reset after return)
\n Sdfatsectornum = Sdtempd ' Step to the next FAT entry and position
\n Sdfatbufferpos = Sdbufferpos ' Update the FAT buffer pointer
\n For Sdtempw = 1 To 512 ' Copy this FAT sector data into Sdfatbuffer
\n Sdfatbuffer(sdtempw) = Sdbuffer(sdtempw)
\n Next Sdtempw
\n End If
\n
\n #if Sdusefsinfo = 1
\n Gosub Sdupdatefsinfo ' Update the fsinfo variables
\n #endif
\n
\n Sdstatus = 0
\n Else ' End of FAT reached and no free FAT entry found (SDstatus = 44)
\n Sdsectord = Sdfatsectornum ' Point back to the last FAT sector
\n End If
\n Else ' End of FAT reached and no free FAT entry found (SDstatus = 44)
\n Sdsectord = Sdfatsectornum ' Point back to the last FAT sector
\n End If
\n Else
\n Sdstatus = 0
\n End If
\n
\n #else ' Unbuffered FAT
\n If Sdsectord < Sdfat2location Then
\n Do
\n Gosub Sdfindfreefatentry
\n Loop Until Sdstatus <> 0
\n If Sdstatus = 43 Then ' New free FAT entry found in another FAT sector
\n Sdstatus = 0
\n Gosub Sdcalculatefatentrycluster ' Calculate Sdclusterd number to store in Sdfatsectornum & Sdfatbufferpos
\n Sdtempd = Sdsectord ' Temporarily store FAT sector number with free position
\n
\n Sdsectord = Sdfatsectornum ' Read the sector containing the FAT entry about to be extended
\n Gosub Sdreadsector
\n If Sdstatus = 0 Then
\n Sdtempw = Sdfatbufferpos
\n For Sdtempb = 1 To Sdfattype ' Update the previous FAT entry with a pointer to the next cluster
\n Sdbuffer(sdtempw) = Sdclusterb(sdtempb)
\n Incr Sdtempw
\n Next Sdtempb
\n Gosub Sdwritesector ' Write the now extended FAT chain sector back to the SD card
\n If Sdstatus = 0 Then
\n Sdwclusterd = Sdclusterd ' Update the write cluster pointer
\n Sdwsecincluster = 1 ' Reset write sector number (Sdwbufferpos is reset after return)
\n Sdfatsectornum = Sdtempd ' Update the FAT sector number
\n Sdfatbufferpos = Sdbufferpos ' Update the FAT buffer pointer
\n
\n #if Sdusefsinfo = 1
\n Gosub Sdupdatefsinfo ' Update the fsinfo variables
\n #endif
\n
\n End If
\n End If
\n
\n Else ' End of FAT reached and no free FAT entry found (SDstatus = 44)
\n Sdsectord = Sdfatsectornum ' Point back to the last FAT sector
\n End If
\n
\n Else ' End of FAT reached and no free FAT entry found (SDstatus = 44)
\n Sdsectord = Sdfatsectornum ' Point back to the last FAT sector
\n End If
\n
\n #endif
\n
\n If Sdstatus = 44 Then ' The partition is full - store FAT EOC marker
\n Sdpartitionfull = 1 ' The partition is full (there are no more free FAT entries)
\n Sdclosefile = 1 ' Close the file
\n Sdstatus = 0 ' Remap Sdstatus
\n End If
\n
\n End If
\n Sdwbufferpos = 1 ' Reset byte counter
\n End If
\n
\n If Sdclosefile = 0 Then
\n Sdbuffer(sdwbufferpos) = Sdbyterw ' Store byte in sector buffer
\n Incr Sdwfilesized ' Increment the file size byte counter
\n Sdsavedatasector = 1
\n End If
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdfinalizeafterwriting:
\n ' Used to close the file after the final call to Sdwritebyte
\n
\n ' Input variables:
\n ' Sdwclusterd = the cluster number we are writing to (set by Sdwritebyte - touch only when writing to > 1 file)
\n ' Sdwsecincluster = the sector in this cluster (set by Sdwritebyte - touch only when writing to > 1 file)
\n '' Sdwbufferpos = the position in this sector (set by Sdwritebyte - touch only when writing to > 1 file)
\n ' Sdwfilesized = the file size (set by Sdwritebyte - touch only when writing to > 1 file)
\n ' Sdfatsectornum = the FAT sector number (set by Sdwritebyte - touch only when writing to > 1 file)
\n ' Sdfatbufferpos = the position in this sector (set by Sdwritebyte - touch only when writing to > 1 file)
\n ' Sddirclusterd = the directory cluster getting file size (set by Sdcreatefileordir or Sdappendfile - touch only when writing to > 1 file)
\n ' Sddirsecincluster = the sector in this cluster (set by Sdcreatefileordir or Sdappendfile - touch only when writing to > 1 file)
\n ' Sddirbufferpos = the position in this sector (set by Sdcreatefileordir or Sdappendfile - touch only when writing to > 1 file)
\n ' Sdbuffer() (touch only when writing to > 1 file)
\n ' Sdfatbuffer() (touch only when writing to > 1 file)
\n ' Sdsavedatasector = 1 if the data should be saved to the SD (set by Sdwritebyte - touch only when writing to > 1 file)
\n
\n ' Output variables:
\n ' Sdclosefile = 0 if the file was closed successfully
\n
\n ' Returned statuses:
\n ' Sdstatus = 0 Successful
\n ' Sdstatus = 7 Timeout
\n ' Sdstatus = 41 Data rejected due to a CRC error
\n ' Sdstatus = 42 Data rejected due to a Write Error
\n
\n Sdclosefile = 1
\n
\n ' Save the current file content sector to the SD card (if we haven't just saved a full data sector to the SD card)
\n If Sdsavedatasector = 1 Then ' Sdsavedatasector = 1 "inside" a data sector and 0 just after the sector has been saved by Sdwritebyte
\n Sdclusterd = Sdwclusterd ' Calculate the absolute sector number for this sector
\n Gosub Sdlocatesector
\n Sdsectord = Sdsectord + Sdwsecincluster
\n Decr Sdsectord
\n
\n #if Sdcleartail = 1
\n Incr Sdwbufferpos
\n For Sdtempw = Sdwbufferpos To Sdbytespersecw
\n Sdbuffer(sdtempw) = 0
\n Next Sdtempw
\n Decr Sdwbufferpos
\n #endif
\n
\n #if Sdwmode = 1
\n Sdwriteorigin = 0
\n #endif
\n Gosub Sdwritesector
\n End If
\n
\n Sdclusterd = &H0FFFFFFF ' Save EOC marker in the FAT sector
\n Gosub Sdsavefatsec
\n
\n Sdstatus = 0
\n ' Update the directory entry with file size and save it to the SD card
\n Sdclusterd = Sddirclusterd ' Point to the directory entry again
\n Sdsecincluster = Sddirsecincluster
\n Sdbufferpos = Sddirbufferpos
\n
\n Gosub Sdlocatedirsector ' Point to the file's directory entry
\n
\n If Sddirclusterd > 0 Then ' Unless we are in the FAT16 root directory
\n Sdsectord = Sdsectord + Sddirsecincluster
\n Decr Sdsectord
\n End If
\n
\n #if Sdwmode = 1
\n Sdreaddestination = 0
\n #endif
\n Gosub Sdreadsector ' Update the directory sector with the new write and access DateTime
\n If Sdstatus = 0 Then
\n Gosub Sdstore29_32 ' Enter file size into the directory entry
\n #if Sdwmode = 1
\n Sdwriteorigin = 0
\n #endif
\n
\n Gosub Sdwritesector ' Write the directory entry back to the SD card
\n Sdclosefile = 0 ' The file was close successfully
\n End If
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdstoredirentry:
\n ' Used to store all information in a new directory entry, except file size, that will be updated at the end in a second read+write to this directory sector
\n
\n ' Input variables:
\n ' Sdentrynames = the name of the new file or subdirectory (or . .. in case of the leading subirectory entries)
\n ' Sdcreatemode 0 = file, 1 = subdirectory
\n ' Sdclusterd = the cluster number where the new file or subdirectory starts
\n ' Sdwfilesized = the file size (0 for subdirectory or when creating a new file)
\n ' Sdbufferpos = the buffer position in the current sector of the current directory cluster
\n ' Sdbuffer() = the current directory sector
\n ' Sdyear = the year
\n ' Sdmonth = the month
\n ' Sdday = the day
\n ' Sdhours = the hours
\n ' Sdminutes = the minutes
\n ' Sdseconds = the seconds
\n ' Sdmseconds = the milliseconds
\n
\n ' Output variables:
\n ' Sdbuffer() = the current directory sector
\n ' Sddatew = the date in DateTime format (normally not used afterwards)
\n ' Sdtimew = the time in DateTime format (normally not used afterwards)
\n
\n Sdtempw = Sdbufferpos
\n For Sdtempb = 1 To 11 ' Store the filename in the new directory entry
\n Sdbuffer(sdtempw) = Sdentrynameb(sdtempb)
\n Incr Sdtempw
\n Next Sdtempb
\n
\n If Sdcreatemode = 0 Then ' Create file
\n Sdbuffer(sdtempw) = &H20 ' Set archive bit - has been changed since last backup
\n Else ' Create subdirectory
\n Sdbuffer(sdtempw) = &H10 ' Set subdirectory bit
\n End If
\n
\n Sdtempw = Sdtempw + 9
\n Sdbuffer(sdtempw) = Sdclusterb(3) ' 21
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sdclusterb(4) ' 22
\n Sdtempw = Sdtempw + 5
\n Sdbuffer(sdtempw) = Sdclusterb(1) ' 27 Store the file's starting cluster number in the new directory entry
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sdclusterb(2) ' 28
\n
\n Gosub Sdstore29_32 ' Enter file size into the directory entry
\n
\n Gosub Sdpreparedatetime ' Calculate and store date and time in the new directory entry
\n Sdtempw = Sdbufferpos + 12
\n Sdbuffer(sdtempw) = 0 ' 13
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sdseconds Mod 2 ' 14
\n Sdbuffer(sdtempw) = Sdbuffer(sdtempw) * 100 ' 14
\n Sdbuffer(sdtempw) = Sdbuffer(sdtempw) + Sdmseconds ' 14
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sdtimeb(1) ' 15
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sdtimeb(2) ' 16
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sddateb(1) ' 17
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sddateb(2) ' 18
\n Incr Sdtempw
\n Gosub Sdstore19_26
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdstore19_26:
\n Sdbuffer(sdtempw) = Sddateb(1) ' 19
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sddateb(2) ' 20
\n Sdtempw = Sdtempw + 3
\n Sdbuffer(sdtempw) = Sdtimeb(1) ' 23
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sdtimeb(2) ' 24
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sddateb(1) ' 25
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sddateb(2) ' 26
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdstore29_32:
\n Sdtempw = Sdbufferpos + 28 ' Enter file size into the directory entry
\n Sdbuffer(sdtempw) = Sdwfilesizeb(1) ' 29
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sdwfilesizeb(2) ' 30
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sdwfilesizeb(3) ' 31
\n Incr Sdtempw
\n Sdbuffer(sdtempw) = Sdwfilesizeb(4) ' 32
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdfindfreefat:
\n ' Used to search FAT1 for a free entry, starting from Sdsectord, and store a number of positions and the FAT1 sector
\n
\n ' Input variables:
\n ' Sdsectord = the FAT1 sector we are starting in (>= Sdfat1location, < Sdfat2location)
\n ' Sdbufferpos = 1 or the actual position
\n
\n ' Output variables:
\n ' Sdfatsectornum = the FAT1 sector in which we found a free entry
\n ' Sdfatbufferpos = the position in this sector
\n ' Sdfatclusterd = the cluster number corresponding to the above FAT1 position
\n ' Sdwclusterd = the cluster number corresponding to the above FAT1 position
\n ' Sdwsecincluster = 1
\n ' Sdwbufferpos = 0 (more practical starting point than 1)
\n ' Sdwfilesized = 0
\n
\n ' Returned statuses:
\n ' 0 = Successful
\n ' 7 = Timeout
\n
\n Sdpartitionfull = 0 ' Assume the partition is not full (there are free FAT entries)
\n
\n Gosub Sdfindfreefatentry
\n
\n If Sdstatus = 43 Then ' Free FAT entry found
\n Sdstatus = 0 ' Remap Sdstatus
\n
\n Sdfatsectornum = Sdsectord ' Store absolute sector position for this FAT entry
\n Sdfatbufferpos = Sdbufferpos ' (This is where we are later going to write the pointer to the next entry)
\n
\n #if Sdwmode = 1 ' Buffered FAT sector writing
\n For Sdtempw = 1 To 512 ' Copy this FAT sector data into Sdfat1buffer
\n Sdfatbuffer(sdtempw) = Sdbuffer(sdtempw)
\n Next Sdtempw
\n #endif
\n
\n Gosub Sdcalculatefatentrycluster ' Calculate cluster number for this FAT entry
\n
\n Sdfatclusterd = Sdclusterd ' Store this FAT entry's corresponding cluster number (not the pointer to the next entry)
\n Sdwclusterd = Sdclusterd ' Set the initial write cluster pointer
\n Sdwsecincluster = 1 ' Set the initial write sector number
\n Sdwbufferpos = 0 ' Set the initial write buffer position (0 is more practical than 1 in this case)
\n Sdwfilesized = 0 ' Reset the file size counter
\n End If
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdfindfreefatentry:
\n ' Used to search FAT1 for a free entry, starting from Sdsectord
\n
\n ' Input variables:
\n ' Assign Sdsectord (>= Sdfat1location, < Sdfat2location)
\n ' Assign Sdbufferpos = 1 or actual position
\n
\n ' Output variables:
\n ' Sdsectord = the FAT1 sector in which we found a free entry
\n ' Sdbufferpos = the position in this sector
\n
\n ' Returned statuses:
\n '' 0 = Successful
\n ' 7 = Timeout
\n ' 43 = Free FAT entry found
\n ' 44 = End of FAT and no free entry found
\n
\n Sdstatus = 0
\n Sdfatcontinue = 1
\n Do
\n
\n ' 2 = write unbuffered
\n ' 1 = write buffered
\n ' 0 = not writing
\n #if Sdwmode = 1
\n Sdreaddestination = 0
\n #endif
\n
\n Gosub Sdreadsector
\n
\n If Sdstatus = 0 Then
\n ' Look for &H0000 (FAT16) or &H00000000 (FAT32)
\n Do
\n Sdtempw = Sdbufferpos
\n If Sdbuffer(sdtempw) = 0 Then ' Byte 1
\n Incr Sdtempw
\n If Sdbuffer(sdtempw) = 0 Then ' Byte 2
\n If Sdfattype = 2 Then ' FAT16
\n Sdstatus = 43 ' Free FAT entry found
\n Sdfatcontinue = 0
\n Else ' FAT32
\n Incr Sdtempw
\n If Sdbuffer(sdtempw) = 0 Then ' Byte 3
\n Incr Sdtempw
\n Sdtempb = Sdbuffer(sdtempw) And &B00001111
\n If Sdtempb = 0 Then ' Byte 4
\n Sdstatus = 43 ' Free FAT entry found
\n Sdfatcontinue = 0
\n End If
\n End If
\n End If
\n End If
\n End If
\n
\n If Sdstatus <> 43 Then
\n Sdbufferpos = Sdbufferpos + Sdfattype
\n End If
\n
\n Loop Until Sdfatcontinue = 0 Or Sdbufferpos > Sdbytespersecw
\n
\n If Sdsectord = Sdfat2location Then
\n Sdfatcontinue = 0
\n If Sdstatus = 0 Then
\n Sdstatus = 44 ' End of FAT and no free entry found
\n End If
\n Else
\n If Sdstatus = 0 Then
\n Incr Sdsectord
\n Sdbufferpos = 1
\n End If
\n End If
\n
\n Else
\n Sdfatcontinue = 0
\n End If
\n
\n Loop Until Sdfatcontinue = 0
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdwclearcluster:
\n ' Used to write zeroes to sectors 2-Sdsecspercluster (which is then followed either by zeroes to sector 1 or the new directory entry or the . .. entries)
\n
\n ' Input variables:
\n ' Sdclusterd = the cluster we are about to clear
\n
\n ' Output variables:
\n ' Sdbuffer() contains 512*zero
\n
\n ' Returned statuses:
\n ' Sdstatus = 0 Successful
\n ' Sdstatus = 7 Timeout
\n ' Sdstatus = 41 Data rejected due to a CRC error
\n ' Sdstatus = 42 Data rejected due to a Write Error
\n
\n
\n ' Gosub Sdlocatesector
\n ' Sdsectord = Sdsectord + Sdsecspercluster ' Now we are at the sector after the one we want...
\n ' For Sdtempw = 1 To 512 ' Keeping the directory nice and tidy
\n ' Sdbuffer(sdtempw) = 0
\n ' Next Sdtempw
\n
\n 'For Sdtempb2 = 2 To Sdsecspercluster
\n ' Decr Sdsectord ' ... and start by subtracting 1 in the loop to start at the last sector in the current cluster
\n ' Gosub Sdwritesector
\n ' If Sdstatus <> 0 Then
\n ' Exit For
\n ' End If
\n ' Next Sdtempb2
\n
\n ' Return
\n
\n '----------------------------------------------------------------------------
\n
\n Sdsavefatsec:
\n ' Used to store next cluster or EOC marker in Sd/fat/buffer() at Sdfatbufferpos and save it back to the SD card (FAT1 and FAT2)
\n
\n ' Input variable:
\n ' Sdfatbufferpos = the FAT entry position
\n ' Sdfatsectornum = the FAT sector number
\n ' Sdclusterd = the next cluster number or EOC marker
\n
\n ' Output variable:
\n ' Sdbuffer()
\n
\n ' Returned statuses:
\n ' Sdstatus = 0 Successful
\n ' Sdstatus = 7 Timeout
\n ' Sdstatus = 41 Data rejected due to a CRC error
\n ' Sdstatus = 42 Data rejected due to a Write Error
\n
\n #if Sdwmode = 2 ' Unbuffered FAT sector
\n Sdstatus = 0
\n Sdsectord = Sdfatsectornum ' FAT1
\n Gosub Sdreadsector
\n If Sdstatus = 0 Then
\n Sdtempw = Sdfatbufferpos
\n For Sdtempb = 1 To Sdfattype
\n Sdbuffer(sdtempw) = Sdclusterb(sdtempb) ' (Lowest EOC byte can range from &HF8 to &HFF)
\n Incr Sdtempw
\n Next Sdtempb
\n Sdsectord = Sdfatsectornum
\n Gosub Sdwritesector
\n If Sdstatus = 0 Then
\n Sdsectord = Sdsectord - Sdfat1location
\n Sdsectord = Sdsectord + Sdfat2location ' FAT2
\n Gosub Sdwritesector
\n End If
\n End If
\n #else ' Buffered FAT sector
\n Sdtempw = Sdfatbufferpos
\n For Sdtempb = 1 To Sdfattype
\n Sdfatbuffer(sdtempw) = Sdclusterb(sdtempb) ' (Lowest EOC byte can range from &HF8 to &HFF)
\n Incr Sdtempw
\n Next Sdtempb
\n Sdstatus = 0
\n Sdsectord = Sdfatsectornum ' FAT1
\n Sdwriteorigin = 1 ' Save from Sdfatbuffer
\n Gosub Sdwritesector
\n If Sdstatus = 0 Then
\n Sdsectord = Sdsectord - Sdfat1location
\n Sdsectord = Sdsectord + Sdfat2location ' FAT2
\n Gosub Sdwritesector
\n End If
\n #endif
\n
\n Return
\n
\n#endif
\n
\n
\n#if Sdwmode > 0 And Sdfsactive = 1
\n
\n Sdcalculatefatentrycluster:
\n ' Used to calculate the cluster number for the FAT entry specified by Sdsectord and Sdbufferpos
\n
\n ' Input variables:
\n ' Sdsectord = the current FAT sector
\n ' Sdbufferpos = the position within it
\n
\n ' Output variable:
\n ' Sdclusterd holds the cluster number
\n
\n ' Calculate cluster number for this FAT entry
\n Sdclusterd = Sdsectord - Sdfat1location
\n Sdclusterd = Sdclusterd * Sdbytespersecw
\n Sdclusterd = Sdclusterd + Sdbufferpos
\n Decr Sdclusterd
\n Sdclusterd = Sdclusterd / Sdfattype
\n ' Incr Sdclusterd ' The first FAT entry refers to cluster 0
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdlocatedirsector:
\n
\n If Sddirclusterd = 0 And Sdfattype = 2 Then
\n Sdsectord = Sdrootdirlocation + Sddirsecincluster
\n Decr Sdsectord
\n Else
\n Sdclusterd = Sddirclusterd
\n Gosub Sdlocatesector
\n End If
\n
\n Return
\n
\n#endif
\n
\n#if Sdwmode > 0
\n #if Sdfsactive = 1 Or Sdusewipe = 1
\n
\n Sdpreparedatetime:
\n ' Used to calculate date and time in the format used in directory entries
\n
\n ' Input variables:
\n ' Sdyear
\n ' Sdmonth
\n ' Sdday
\n ' Sdhours
\n ' Sdminutes
\n ' Sdseconds
\n
\n ' Output variables:
\n ' Sddatew holds the date
\n ' Sdtimew holds the time
\n
\n ' Internally used variables:
\n ' Sdtempb
\n
\n ' Date and Time Formats
\n ' Many FAT file systems do not support Date/Time other than DIR_WrtTime and DIR_WrtDate.
\n ' For this reason, DIR_CrtTimeMil, DIR_CrtTime, DIR_CrtDate, and DIR_LstAccDate are actually optional fields.
\n ' DIR_WrtTime and DIR_WrtDate must be supported, however.
\n ' If the other date and time fields are not supported, they should be set to 0 on file create and ignored on other file operations.
\n
\n ' Date Format. A FAT directory entry date stamp is a 16-bit field that is basically a date relative to the MS-DOS epoch of 01/01/1980.
\n ' Here is the format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 16-bit word):
\n
\n ' Bits 0-4: Day of month, valid value range 1-31 inclusive.
\n ' Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive.
\n ' Bits 9-15: Count of years from 1980, valid value range 0-127 inclusive (1980-2107).
\n
\n ' Time Format. A FAT directory entry time stamp is a 16-bit field that has a granularity of 2 seconds.
\n ' Here is the format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 16-bit word).
\n
\n ' Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds).
\n ' Bits 5-10: Minutes, valid value range 0-59 inclusive.
\n ' Bits 11-15: Hours, valid value range 0-23 inclusive.
\n
\n ' The valid time range is from Midnight 00:00:00 to 23:59:58.
\n
\n Sddatew = 0
\n Sddateb(2) = Sdyear - 1980
\n Sddateb(1) = Sdmonth
\n Shift Sddateb(1) , Left , 4
\n Shift Sddatew , Left , 1
\n Sddateb(1) = Sddateb(1) Or Sdday
\n
\n Sdtimew = 0
\n Sdtimeb(2) = Sdhours
\n Sdtimeb(1) = Sdminutes
\n Shift Sdtimeb(1) , Left , 2
\n Shift Sdtimew , Left , 3
\n Sdtempb = Sdseconds / 2
\n Sdtimeb(1) = Sdtimeb(1) Or Sdtempb
\n
\n Return
\n
\n #endif
\n#endif
\n
\n'===============================================================================
\n
\n#if Sdusefsinfo = 1
\n
\n Sdreadfsinfo:
\n ' Used to read the fsinfo variables
\n
\n ' Input variable
\n ' None
\n
\n ' Output variables:
\n ' Sdfsinfofreeclustersd holds the number of free clusters
\n ' Sdfsinfonextfreeclusterd points to the next unused cluster (typically not the first free re-usable cluster)
\n
\n ' Returned statuses:
\n ' Sdstatus = 0 Successful
\n ' Sdstatus = 7 Timeout
\n
\n If Sdfattype = 4 Then
\n Sdsectord = Sdfat32fsinfolocationw
\n
\n ' 2 = write unbuffered
\n ' 1 = write buffered
\n ' 0 = not writing
\n #if Sdwmode = 1
\n Sdreaddestination = 0
\n #endif
\n
\n Gosub Sdreadsector
\n If Sdstatus = 0 Then
\n Sdfsinfofreeclustersb(1) = Sdbuffer(489)
\n Sdfsinfofreeclustersb(2) = Sdbuffer(490)
\n Sdfsinfofreeclustersb(3) = Sdbuffer(491)
\n Sdfsinfofreeclustersb(4) = Sdbuffer(492)
\n
\n Sdfsinfonextfreeclusterb(1) = Sdbuffer(493)
\n Sdfsinfonextfreeclusterb(2) = Sdbuffer(494)
\n Sdfsinfonextfreeclusterb(3) = Sdbuffer(495)
\n Sdfsinfonextfreeclusterb(4) = Sdbuffer(496)
\n End If
\n End If
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdwritefsinfo:
\n ' Used to write the fsinfo variables back to the SD card (after being updated)
\n
\n ' Input variables:
\n ' Sdfsinfofreeclustersd holds the number of free clusters
\n ' Sdfsinfonextfreeclusterd points to the next unused cluster (typically not the first free re-usable cluster)
\n
\n ' Output variable
\n ' None
\n
\n ' Returned statuses:
\n ' Sdstatus = 0 Successful
\n ' Sdstatus = 7 Timeout
\n ' Sdstatus = 41 Data rejected due to a CRC error
\n ' Sdstatus = 42 Data rejected due to a Write Error
\n
\n If Sdfattype = 4 Then
\n Sdsectord = Sdfat32fsinfolocationw
\n
\n ' 2 = write unbuffered
\n ' 1 = write buffered
\n ' 0 = not writing
\n #if Sdwmode = 1
\n Sdreaddestination = 0
\n #endif
\n
\n Gosub Sdreadsector
\n If Sdstatus = 0 Then
\n Sdbuffer(489) = Sdfsinfofreeclustersb(1)
\n Sdbuffer(490) = Sdfsinfofreeclustersb(2)
\n Sdbuffer(491) = Sdfsinfofreeclustersb(3)
\n Sdbuffer(492) = Sdfsinfofreeclustersb(4)
\n
\n Sdbuffer(493) = Sdfsinfonextfreeclusterb(1)
\n Sdbuffer(494) = Sdfsinfonextfreeclusterb(2)
\n Sdbuffer(495) = Sdfsinfonextfreeclusterb(3)
\n Sdbuffer(496) = Sdfsinfonextfreeclusterb(4)
\n
\n ' 2 = write unbuffered
\n ' 1 = write buffered
\n ' 0 = not writing
\n #if Sdwmode = 1
\n Sdwriteorigin = 0
\n #endif
\n
\n Gosub Sdwritesector
\n End If
\n End If
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdupdatefsinfo:
\n ' Used when an additional cluster is being put into use
\n
\n ' Input variables:
\n ' Sdfatclusterd = the cluster we have just started using
\n ' Sdfsinfofreeclustersd holds the previous number of free clusters
\n ' Sdfsinfonextfreeclusterd points to the previous unused cluster (typically not the first free re-usable cluster)
\n
\n ' Output variables:
\n ' Sdfsinfofreeclustersd holds the updated number of free clusters
\n ' Sdfsinfonextfreeclusterd points to the next unused cluster (typically not the first free re-usable cluster)
\n
\n If Sdfattype = 4 Then
\n If Sdfatclusterd >= Sdfsinfonextfreeclusterd Then
\n Sdfsinfonextfreeclusterd = Sdfatclusterd + 1
\n End If
\n Decr Sdfsinfofreeclustersd
\n End If
\n Return
\n
\n#endif
\n
\n
\n#if Sdusedirlist = 1
\n
\n Sddirlist: ' Currently assumes we never fill the SD card completely !!!
\n ' Used to scroll forward and backward through the current directory
\n ' Call this routine in a loop in which you check for certain Sdstatus values
\n ' Reset Sdstatus to 0 before the next step in the loop
\n
\n ' In the very first call to a new directory, assign real or dummy Sdclusterd. If you are listing the root, set it to dummy value 0 to also support FAT16 root dir.
\n ' In the very first call to a new directory, assign Sddirlistarraycounter = 0
\n ' Always assign Sddirlistdirection, 0 = forward, 1 = backward
\n
\n ' Routine-specific Sdstatuses:
\n ' 26 = A file entry has been found
\n ' 27 = A directory entry has been found
\n ' 28 = An available directory space has been found
\n ' 32 = EOD End Of Directory marker found
\n ' 33 = Subdirectory . or .. entry found
\n ' 34 = A volume ID has been found
\n ' 36 = Long file name found
\n
\n ' Since the first directory entry can't have both status and start of directory status, this bit indicates that we have returned to the starting point
\n ' Sddirliststartpoint = 1 ' The directory backward listing has reached the starting point
\n ' Sddirlistendpoint = 1 ' The directory forward listing has reached the end point
\n ' Sddirlistoutside = 1 ' We have scrolled outside of Sddirlistarray() array
\n
\n
\n ' Special handling of root directory
\n If Sdclusterd = 0 Then
\n If Sdfattype = 2 Then ' FAT16 root directory
\n Sdsectorend = Sdsecsinroot
\n Else
\n Sdclusterd = Sdfat32rootclusterd ' FAT32 root directory remapped to (normally) cluster 2
\n End If
\n End If
\n
\n ' If not in FAT16 root directory, locate the first directory sector
\n If Sdclusterd > 0 Then
\n Sdsectorend = Sdsecspercluster
\n End If
\n
\n If Sddirlistarraycounter = 0 Then ' Very first call
\n Sddirliststartpoint = 1 ' Prevent going backward from the starting point
\n Sddirlistendpoint = 0
\n Sddirlistarraycounter = 1
\n Sddirlistarraypointer = 1
\n Sddirlistoutside = 0
\n Sdbufferpos = 1
\n Sdsecincluster = 1
\n Sddirlistarray(1) = Sdclusterd
\n
\n If Sdclusterd = 0 Then
\n Sdsectord = Sdrootdirlocation
\n Else
\n Gosub Sdlocatesector
\n End If
\n Gosub Sdreadsector
\n Else ' All subsequent calls
\n If Sddirlistdirection = 0 Then ' Forward
\n Sddirliststartpoint = 0
\n Sdbufferpos = Sdbufferpos + 32
\n If Sdbufferpos > Sdbytespersecw Then
\n Sdbufferpos = 1
\n Incr Sdsecincluster
\n If Sdsecincluster > Sdsectorend Then
\n If Sdclusterd > 0 Then
\n Sdsecincluster = 1
\n If Sddirlistarraypointer >= Sddirlistarraycounter Then ' We are pointing to or after the last stored cluster
\n If Sddirlistarraypointer >= Sddirlistarraysize Then ' We are pointing to or after the last entry in Sddirlistarray() array - continue outside of it
\n Sddirlistoutside = 1 ' We Have Scrolled Outside Of Sddirlistarray() Array
\n Sddirlistnextclusterd = Sdclusterd ' Store the soon-to-be-previous cluster som we can go back to it if EOD reached later
\n Gosub Sdlocatenextcluster ' Read next cluster
\n Gosub Sdcheckclusterreference ' Check if it indicates EOC (in that case Sdstatus = 31)
\n If Sdstatus = 0 And Sddirlistendpoint = 0 Then
\n Incr Sddirlistarraypointer
\n Gosub Sdlocatesector
\n Gosub Sdreadsector
\n Sdbufferpos = 1
\n Else ' In case of EOD marker found, point to the last valid directory entry
\n Sdclusterd = Sddirlistnextclusterd
\n Gosub Sdlocatesector
\n Sdsectord = Sdsectord + Sdsecspercluster
\n Decr Sdsectord
\n Sdbufferpos = Sdbytespersecw - 31
\n Sdsecincluster = Sdsecspercluster
\n Gosub Sdreadsector
\n End If
\n Else ' We are still before the end of the array
\n Gosub Sdlocatenextcluster ' Read and append next cluster to the cluster array
\n Gosub Sdcheckclusterreference ' Check if it indicates EOC (in that case Sdstatus = 31)
\n If Sdstatus = 0 And Sddirlistendpoint = 0 Then
\n Incr Sddirlistarraycounter
\n Incr Sddirlistarraypointer
\n Sddirlistarray(sddirlistarraypointer) = Sdclusterd
\n Gosub Sdlocatesector
\n Gosub Sdreadsector
\n Sdbufferpos = 1
\n Else ' In case of EOD marker found, point to the last valid directory entry
\n Sdclusterd = Sddirlistarray(sddirlistarraypointer)
\n Gosub Sdlocatesector
\n Sdsectord = Sdsectord + Sdsecspercluster
\n Decr Sdsectord
\n Sdbufferpos = Sdbytespersecw - 31
\n Sdsecincluster = Sdsecspercluster
\n Gosub Sdreadsector
\n End If
\n End If
\n Else ' Point to the next cluster in the array
\n Incr Sddirlistarraypointer
\n Sdclusterd = Sddirlistarray(sddirlistarraypointer)
\n Incr Sdsectord
\n Gosub Sdreadsector
\n End If
\n Else ' End of the FAT16 root
\n Sddirlistendpoint = 1
\n Decr Sdsecincluster ' Point back to the last entry
\n Sdbufferpos = Sdbytespersecw - 31
\n End If
\n Else
\n Incr Sdsectord
\n Gosub Sdreadsector
\n End If
\n End If
\n Else ' Backward
\n If Sddirliststartpoint = 0 Then ' Only allow backward if we are not at the starting point
\n Sddirlistendpoint = 0 ' We are no longer at the end of the directory
\n If Sdbufferpos > 32 Then
\n Sdbufferpos = Sdbufferpos - 32
\n Sddirliststartpoint = 0
\n Else
\n Sdbufferpos = Sdbytespersecw - 31
\n If Sdsecincluster > 1 Then
\n Decr Sdsecincluster
\n Decr Sdsectord
\n Gosub Sdreadsector
\n Else
\n Sdsecincluster = Sdsecspercluster
\n If Sddirlistoutside = 1 Then ' We are outside of Sddirlistarray() array
\n Sddirlistcurrclusterd = Sdclusterd ' Locate the cluster before the current cluster
\n Sdclusterd = Sddirlistarray(sddirlistarraysize)
\n Do
\n Sddirlistnextclusterd = Sdclusterd
\n Gosub Sdlocatenextcluster
\n Gosub Sdcheckclusterreference ' Check if it indicates EOC (in that case Sdstatus = 31)
\n Loop Until Sdstatus <> 0 Or Sdclusterd = Sddirlistcurrclusterd
\n If Sdstatus = 0 Then
\n Decr Sddirlistarraypointer
\n If Sddirlistarraypointer <= Sddirlistarraysize Then
\n Sddirlistoutside = 0
\n End If
\n Sdclusterd = Sddirlistnextclusterd
\n Gosub Sdlocatesector
\n Sdsectord = Sdsectord + Sdsecspercluster
\n Decr Sdsectord
\n Gosub Sdreadsector
\n End If
\n Elseif Sddirlistarraypointer > 1 Then
\n Decr Sddirlistarraypointer
\n Sdclusterd = Sddirlistarray(sddirlistarraypointer)
\n Gosub Sdlocatesector
\n Sdsectord = Sdsectord + Sdsecspercluster
\n Decr Sdsectord
\n Gosub Sdreadsector
\n End If
\n End If
\n End If
\n If Sdclusterd = Sddirlistarray(1) And Sdsecincluster = 1 And Sdbufferpos = 1 Then
\n Sddirliststartpoint = 1 ' Back at the starting point
\n End If
\n End If
\n End If
\n End If
\n
\n
\n ' Check this directory entry
\n If Sdstatus = 0 Then
\n If Sdbuffer(sdbufferpos) = &H00 Then ' End of directory marker
\n Sdstatus = 32 ' EOD End Of Directory marker found
\n Elseif Sdbuffer(sdbufferpos) = &HE5 Then ' Empty directory entry - previous file was deleted
\n Sdstatus = 28 ' An available directory space has been found
\n Elseif Sdbuffer(sdbufferpos) = &H2E Then ' One of first two entries in a subdirectory, . contains the current cluster, .. points to parent directory
\n Sdstatus = 33 ' Subdirectory . or .. entry found
\n Else
\n Sdtempw = Sdbufferpos + 11 ' Check attribute byte
\n Sdtempb = Sdbuffer(sdtempw) Or &B11110000
\n If Sdtempb = &HFF Then
\n Sdstatus = 36 ' Long file name found
\n Elseif Sdbuffer(sdtempw).4 = 1 Then
\n Sdstatus = 27 ' Subdirectory found
\n Elseif Sdbuffer(sdtempw).3 = 1 Then
\n Sdstatus = 34 ' Volume ID found
\n Else
\n Sdstatus = 26 ' File found
\n End If
\n End If
\n
\n ' Store the current directory entry in Sddirlistdirentry
\n Sdtempw = Sdbufferpos ' Make a copy of this directory entry byte by byte
\n Sdtempb = 1
\n For Sdtempb = 1 To 32
\n Sddirlistdirentry(sdtempb) = Sdbuffer(sdtempw)
\n Incr Sdtempw
\n Next Sdtempb
\n
\n If Sddirlistdirentry(1) = &H05 Then ' Substitute for 0xE5 in the Japanese KANJI character set
\n Sddirlistdirentry(1) = &HE5
\n End If
\n
\n End If
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdcheckclusterreference: ' Check if it indicates EOC (>=&HFFF8 or >=&H0FFFFFF8)
\n If Sdfattype = 2 Then ' FAT16
\n Sdclusterb(3) = 0
\n Sdclusterb(4) = 0
\n If Sdclusterd > &HFFF7 Then ' EOC End OF Cluster chain found
\n Sddirlistendpoint = 1
\n #if Sduseappend = 1
\n Sdstatus = 31
\n #endif
\n End If
\n 'Elseif Sdfattype = 4 Then ' FAT32
\n ' Sdclusterb(4) = Sdclusterb(4) And &B00001111
\n ' If Sdclusterd > &H0FFFFFF7 Then ' EOC End OF Cluster chain found
\n ' Sddirlistendpoint = 1
\n ' #if Sduseappend = 1
\n ' Sdstatus = 31
\n ' #endif
\n ' End If
\n End If
\n
\n Return
\n
\n#endif
\n
\n
\n#if Sduselfn = 1
\n
\n Sdlookforlfn:
\n
\n ' Call after Sddirlist has returned with Sdstatus = 26 (file) or 27 (subdirectory)
\n
\n For Sdtempb = 1 To 32 ' Copy the directory entry
\n Sdlfndirentry(sdtempb) = Sddirlistdirentry(sdtempb)
\n Next Sdtempb
\n
\n Sddirlistdirection = 1 ' Read the previous directory entry
\n Sdlfncontinue = 1
\n Sdlfnfound = 0
\n Sdtempb4 = 1 ' Expected starting point for the long filename ordinal
\n
\n Do
\n If Sddirliststartpoint = 0 Then ' 0 = the directory backward listing has NOT reached the starting point
\n Sdstatus = 0
\n Gosub Sddirlist
\n If Sdstatus = 36 Then
\n Sdtempb = Sddirlistdirentry(1) And &B00011111
\n If Sdtempb = Sdtempb4 Then ' Expected ordinal number found
\n If Sdtempb = 1 Then
\n Gosub Sdcalculatelfnchecksum
\n End If
\n If Sdlfnchecksum = Sddirlistdirentry(14) Then ' Matching checksum found
\n Sdtempb = Sdtempb4 - 1 ' Calculate the starting point in the string for these 13 characters
\n Sdtempb = Sdtempb * 13
\n Sdtempb2 = 0
\n Do
\n Sdtempb2 = Sdtempb2 + 2
\n Incr Sdtempb
\n If Sdtempb2 = 12 Then
\n Sdtempb2 = 15
\n Elseif Sdtempb2 = 27 Then
\n Sdtempb2 = 29
\n End If
\n If Sddirlistdirentry(sdtempb2) > 0 And Sddirlistdirentry(sdtempb2) < 255 Then ' Don't append NULL &H0000 and padding &HFFFF at the end of the name
\n Sdlfnb(sdtempb) = Sddirlistdirentry(sdtempb2) ' Append the characters from this directory entry
\n End If
\n Loop Until Sdtempb2 = 31
\n Incr Sdtempb4
\n If Sddirlistdirentry(1).6 = 1 Then ' Stop bit found
\n Sdlfnfound = 1 ' We have read a complete long filename
\n Sdlfncontinue = 0
\n End If
\n Else
\n Sdlfncontinue = 0 ' Checksum is not matching
\n End If
\n Else
\n Sdlfncontinue = 0 ' Expected ordinal number not found
\n End If
\n Else
\n Sdlfncontinue = 0 ' Record is not a long filename entry
\n End If
\n Else
\n Sdlfncontinue = 0 ' Current record is the very first directory entry
\n End If
\n Loop Until Sdlfncontinue = 0
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdcalculatelfnchecksum:
\n Sdlfnchecksum = Sdlfndirentry(1)
\n For Sdtempb = 2 To 11
\n Sdtempb2 = Sdlfnchecksum
\n Shift Sdtempb2 , Right , 1
\n Sdtempb3 = Sdlfnchecksum And &B00000001
\n Shift Sdtempb3 , Left , 7
\n Sdlfnchecksum = Sdlfndirentry(sdtempb) + Sdtempb2
\n Sdlfnchecksum = Sdlfnchecksum + Sdtempb3
\n Next Sdtempb
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n #if Sduselfncompare = 1
\n Sdcomparefilenames:
\n Sdlfnfound = 0
\n Sdlfncontinue = 1
\n Sdtempb = 0
\n Do
\n Incr Sdtempb
\n If Sdlfnb(sdtempb) <> 0 Then ' End marker
\n If Sdlfnb(sdtempb) <> Sdlfn2b(sdtempb) Then
\n Sdlfncontinue = 0
\n End If
\n Else
\n Sdlfncontinue = 0
\n If Sdtempb > 1 Then
\n Sdlfnfound = 1
\n End If
\n End If
\n Loop Until Sdlfncontinue = 0 Or Sdtempb = 255
\n Return
\n #endif
\n
\n#endif
\n
\n'-------------------------------------------------------------------------------
\n
\n#if Sdusewipe = 1
\n
\n Sdwipe:
\n ' Used to clean out and reset FAT1, FAT2, root directory, and fsinfo sector.
\n ' This is NOT a real formatting!
\n
\n ' Input variables
\n ' Sdentrynames with all 11 characters including space characters
\n ' Sdyear
\n ' Sdmonth
\n ' Sdday
\n ' Sdhours
\n ' Sdminutes
\n ' Sdseconds
\n
\n For Sdtempw = 1 To 512
\n Sdbuffer(sdtempw) = 0
\n Next Sdtempw
\n
\n #if Sdwmode = 1
\n Sdwriteorigin = 0
\n #endif
\n
\n If Sderaseall = 1 Then ' Erase everything from the beginning of FAT1 to the last sector in this partition
\n Sdtempd = Sdtotsecsd + Sdpartstart
\n Else
\n Sdtempd = Sddataareastart + Sdsecspercluster ' Erase everything from the beginning of FAT1 to the end of cluster 2
\n End If
\n
\n Sdstatus = 0
\n
\n Sdsectord = Sdfat1location
\n While Sdsectord < Sdtempd
\n Gosub Sdwritesector
\n Incr Sdsectord
\n Wend
\n
\n Sdstatus = 0
\n
\n ' Then write FAT pointers to dummy clusters 0 and 1 (and 2 if FAT32)
\n Sdbuffer(1) = &HF8
\n Sdbuffer(2) = &HFF
\n Sdbuffer(3) = &HFF
\n
\n If Sdfattype = 2 Then ' FAT16 F8FF FFFF
\n Sdbuffer(4) = &HFF
\n Else
\n Sdbuffer(4) = &H0F ' FAT32 F8FFFF0F FFFFFFFF FFFFFF0F
\n For Sdtempb = 5 To 11
\n Sdbuffer(sdtempb) = &HFF
\n Next Sdtempb
\n Sdbuffer(12) = &H0F
\n End If
\n
\n Sdsectord = Sdfat1location
\n Gosub Sdwritesector
\n Sdsectord = Sdfat2location
\n Gosub Sdwritesector
\n
\n ' Then store the new volume ID in the root directory
\n ' 1-11 = Name
\n ' 12 = &H08
\n ' 23-26 = timestamp
\n For Sdtempb = 1 To 11
\n Sdbuffer(sdtempb) = Sdentrynameb(sdtempb)
\n Next Sdtempb
\n Sdbuffer(12) = &H08
\n
\n Gosub Sdpreparedatetime
\n
\n Sdbuffer(23) = Sdtimeb(1)
\n Sdbuffer(24) = Sdtimeb(2)
\n Sdbuffer(25) = Sddateb(1)
\n Sdbuffer(26) = Sddateb(2)
\n
\n If Sdfattype = 2 Then
\n Sdsectord = Sdrootdirlocation
\n Else
\n Sdsectord = Sddataareastart
\n End If
\n
\n Gosub Sdwritesector
\n
\n ' Finally update fsinfo sector
\n #if Sdusefsinfo = 1
\n
\n If Sdfattype = 4 Then
\n
\n Gosub Sdreadfsinfo
\n
\n Sdfsinfofreeclustersd = Sdtotsecsd - Sddataareastart
\n Incr Sdfsinfofreeclustersd
\n Sdfsinfofreeclustersd = Sdfsinfofreeclustersd / Sdsecspercluster
\n Decr Sdfsinfofreeclustersd ' The first cluster (2) is used by the FAT32 root directory
\n
\n Sdfsinfonextfreeclusterd = 3
\n
\n Sdbuffer(489) = Sdfsinfofreeclustersb(1)
\n Sdbuffer(490) = Sdfsinfofreeclustersb(2)
\n Sdbuffer(491) = Sdfsinfofreeclustersb(3)
\n Sdbuffer(492) = Sdfsinfofreeclustersb(4)
\n
\n Sdbuffer(493) = Sdfsinfonextfreeclusterb(1)
\n Sdbuffer(494) = Sdfsinfonextfreeclusterb(2)
\n Sdbuffer(495) = Sdfsinfonextfreeclusterb(3)
\n Sdbuffer(496) = Sdfsinfonextfreeclusterb(4)
\n
\n Gosub Sdwritefsinfo
\n
\n End If
\n
\n #endif
\n
\n
\n Return
\n
\n#endif
\n
\n'-------------------------------------------------------------------------------
\n
\n#if Sdusesizeinfo = 1
\n
\n Sdreceivebuffer18:
\n Spiin Sdbuffer(1) , 18
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdrequestcid:
\n
\n Sdcommand = &HFF ' Clock SD to complete job
\n Gosub Sdcommand1
\n ' Gosub Sdcommand1
\n
\n Reset Sd_cs
\n
\n ' Sdcommand = &HFF ' Clock SD to complete job
\n Gosub Sdcommand1
\n ' Gosub Sdcommand1
\n
\n Sdcommand = &H4A ' Send CMD10
\n Gosub Sdcommand1
\n Sdcommand = &H00
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Sdcommand = &H1D
\n Gosub Sdcommand1
\n
\n Sdexpectedresponse = &H00 ' First response after CMD9
\n Gosub Sdseekresponse
\n If Sdstatus = 0 Then
\n Sdexpectedresponse = &HFE ' Start token after CMD9
\n Gosub Sdseekresponse
\n If Sdstatus = 0 Then
\n Gosub Sdreceivebuffer18
\n End If
\n End If
\n
\n Reset Sd_cs
\n
\n Sdcommand = &HFF ' Clock SD to complete job
\n Gosub Sdcommand1
\n 'Gosub Sdcommand1
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdrequestcsd:
\n
\n ' 16 bytes, MSB first
\n
\n Sdcommand = &HFF ' Clock SD to complete job
\n Gosub Sdcommand1
\n 'Gosub Sdcommand1
\n
\n Reset Sd_cs
\n
\n ' Sdcommand = &HFF ' Clock SD to complete job
\n Gosub Sdcommand1
\n ' Gosub Sdcommand1
\n
\n Sdcommand = &H49 ' Send CMD9
\n Gosub Sdcommand1
\n Sdcommand = &H00
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Sdcommand = &HAF
\n Gosub Sdcommand1
\n
\n Sdexpectedresponse = &H00 ' First response after CMD9
\n Gosub Sdseekresponse
\n If Sdstatus = 0 Then
\n Sdexpectedresponse = &HFE ' Start token after CMD9
\n Gosub Sdseekresponse
\n If Sdstatus = 0 Then
\n Gosub Sdreceivebuffer18
\n End If
\n End If
\n
\n Reset Sd_cs
\n
\n Sdcommand = &HFF ' Clock SD to complete job
\n Gosub Sdcommand1
\n 'Gosub Sdcommand1
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdcalculatesize: ' Can be called after Sdrequestcsd
\n
\n ' v2+
\n ' Bits 127-126 = 01 (byte 1.6 = 1, 1.7 = 0)
\n ' C_SIZE 22 bits 69-48 (bytes 8&B00111111,9,10)
\n ' Size = C_SIZE * 2^19
\n
\n ' v1.x:
\n ' Bits 127-126 = 00
\n ' C_SIZE 12 bits 73-62 (bytes 7&B00000011, 8, 9&B11000000)
\n ' C_SIZE_MULT 3 bits 49-47 (bytes 10&B00000011, 11&B10000000)
\n ' READ_BL_LEN 4 bits 84-80 (byte 6&B00001111)
\n ' Size = (C_SIZE+1) * 2^(C_SIZE_MULT+2) * 2^READ_BL_LEN
\n
\n If Sdbuffer(1).6 = 1 And Sdbuffer(1).7 = 0 Then
\n Sdcsize = &B00111111 And Sdbuffer(8) ' v2+
\n Sdcsize = Sdbuffer(8)
\n Shift Sdcsize , Left , 8
\n Sdcsize = Sdcsize + Sdbuffer(9)
\n Shift Sdcsize , Left , 8
\n Sdcsize = Sdcsize + Sdbuffer(10)
\n Incr Sdcsize
\n Shift Sdcsize , Right , 1 ' Size in MB (1k = 1024)
\n Else
\n Sdcsize = &B00000011 And Sdbuffer(7) ' v1.x ok
\n Shift Sdcsize , Left , 8
\n Sdcsize = Sdcsize + Sdbuffer(8)
\n Shift Sdcsize , Left , 8
\n Sdcsize = Sdcsize + Sdbuffer(9)
\n Shift Sdcsize , Right , 6
\n
\n Sdcsizemult = Sdbuffer(10) And &B00000011
\n Shift Sdcsizemult , Left , 1
\n If Sdbuffer(11).7 = 1 Then
\n Incr Sdcsizemult
\n End If
\n
\n Sdreadbllen = Sdbuffer(6) And &B00001111
\n
\n Incr Sdcsize
\n Shift Sdcsize , Left , Sdcsizemult
\n Shift Sdcsize , Left , Sdreadbllen
\n Shift Sdcsize , Right , 18 ' Size in MB (1k = 1024)
\n ' Size = (C_SIZE+1) * 2^(C_SIZE_MULT+2) * 2^READ_BL_LEN
\n End If
\n
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Sdrequeststatus:
\n
\n Sdcommand = &HFF ' Clock SD to complete job
\n Gosub Sdcommand1
\n ' Gosub Sdcommand1
\n
\n Reset Sd_cs
\n
\n ' Sdcommand = &HFF ' Clock SD to complete job
\n Gosub Sdcommand1
\n ' Gosub Sdcommand1
\n
\n Sdcommand = &H4D ' Send CMD13
\n Gosub Sdcommand1
\n Sdcommand = &H00
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Gosub Sdcommand1
\n Sdcommand = &H0D
\n Gosub Sdcommand1
\n
\n Sdtempb = 0
\n Do
\n Gosub Sdresponse1
\n Incr Sdtempb
\n Loop Until Sdresponse(1) <> 255 Or Sdtempb = 255
\n
\n If Sdresponse(1) = 255 Then
\n Sdstatus = 6 ' Timeout in CMD13
\n Else
\n Gosub Sdresponse2_5
\n End If
\n
\n Reset Sd_cs
\n
\n Sdcommand = &HFF ' Clock SD to complete job
\n Gosub Sdcommand1
\n 'Gosub Sdcommand1
\n
\n Return
\n
\n#endif
\n
\n'-------------------------------------------------------------------------------
\n
\n#if Sdusecrc7 = 1
\n
\n Sdcheckresponsecrc7: ' Receives the SD response and checks the CRC
\n Sdcrc7byte = Sdcrc7(sdresponse(1))
\n If Sdresponse(6) <> Sdcrc7byte Then
\n Sdstatus = 129
\n End If
\n Return
\n
\n '-------------------------------------------------------------------------------
\n
\n Function Sdcrc7(byval Sdarray As Byte) As Byte ' Calculates CRC7 for the 5 first bytes of Sdarray
\n
\n Local Sdm As Byte ' Array byte loop
\n Local Sdk As Byte ' Byte bit loop
\n Local Sdx As Byte ' Current array byte value (could be skipped and work only with Sdarray(m))
\n Local Sdcrc7sum As Byte ' The CRC7 being calculated
\n Local Sdcalcstep As Byte ' Intermediate step necessary for BASCOM
\n
\n Sdcrc7sum = 0
\n
\n For Sdm = 1 To 5 ' Loop through the 5 first array bytes
\n Sdx = Sdarray(sdm)
\n
\n For Sdk = 0 To 7 ' Loop through the byte bitwise
\n
\n Shift Sdcrc7sum , Left , 1 ' Shift CRC left
\n Sdcalcstep = Sdx Xor Sdcrc7sum
\n
\n If Sdcalcstep.7 = 1 Then ' Do XOR if MSB = 1
\n Sdcrc7sum = Sdcrc7sum Xor &H9
\n End If
\n
\n Shift Sdx , Left , 1 ' Shift current array byte value left
\n
\n Next Sdk
\n
\n Sdcrc7sum = Sdcrc7sum And &H7F
\n
\n Next Sdm
\n
\n Shift Sdcrc7sum , Left , 1 ' Shift left and add 1
\n Sdcrc7sum = Sdcrc7sum + 1
\n Sdcrc7 = Sdcrc7sum
\n
\n End Function
\n
\n#endif
\n
\n'===============================================================================
\nInteruption_timer2:
\nStop Timer2 ' adjust timing
\nnop ' adjust timing
\nnop
\nnop
\nnop
\nnop
\nnop
\nnop
\nnop
\nnop
\nnop
\nnop
\nnop
\nnop
\nnop
\nnop
\nnop
\nnop
\nnop
\nnop
\n
\n
\nX1 = X1 + 1
\n
\nPwm1a = Buffer1(x1) ' send data to pwm
\nTimer2 = 73 '127 for 0.5 mhz 166 for 1 mhz 73 for 4 mhz ' 22khz 160=255-(16mhz/4/21010hz)+time processing
\nStart Timer2
\n
\nIf X1 = 256 Then X1 = 0 '257
\n
\nReturn
\n
\n
\n
\n'wwwwwwwwwwwwwwwwwww
\nEnd ' End program
\n
\n
\n'===============================================================================
\n
\n
\n'$include "KokkeKat_FAT-free_SD_lib_code.bas"
\n'$include "3310endshiftout.bas" ' <----- This is a display library I used when developing, so it's not required by the SD card lib[/code]
\n
\nSegue agora o arquivo de definições ....
\n
\n[code]' KokkeKat FAT-free SD library declarations for SDSC, SDHC, and SDXC - INCLUDE at the beginning of your code
\n' Written by Niclas Arndt, Stockholm, Sweden, 2011.05.06
\n' License terms apply, as stated in the application note
\n
\n' Developer switches:
\n
\n' 1 = minimum detail (only make sure that the init is successful)
\n' 0 = full detail (return full detail if init is unsuccessful)
\nConst Sdinitdetail = 1
\n
\n' 1 = FAT16/32 file system active
\n' 0 = FAT16/32 file system not active (only read and write raw sectors)
\nConst Sdfsactive = 1
\n
\n' 1 = Use the FIND routine
\n' 0 = Don't use the FIND routine
\nConst Sdusefind = 1
\n
\n' 1 = Enable Sdusefindstoreentry
\n' 0 = Don't enable Sdusefindstoreentry
\nConst Sdusefindstoreentry = 0
\n
\n' 1 = Use Sddirlist
\n' 0 = Don't use Sddirlist
\nConst Sdusedirlist = 0 ' Use or don't use
\nConst Sddirlistarraysize = 12 ' If used, set the size of the array that holds the cluster numbers
\n
\n' 1 = read
\n' 0 = not reading
\nConst Sdrmode = 1
\n
\n' 2 = write unbuffered
\n' 1 = write buffered
\n' 0 = not writing
\nConst Sdwmode = 0
\n
\n' 1 = Use Sdappend
\n' 0 = Don't use Sdappend
\nConst Sduseappend = 1
\n
\n' 1 = Clear the unused end of the sector before writing it to the SD card
\n' 0 = Don't clear the unused end of the sector before writing it to the SD card
\nConst Sdcleartail = 0
\n
\n' 1 = Use FAT32 fsinfo sector data
\n' 0 = Don't use FAT32 fsinfo sector
\nConst Sdusefsinfo = 0
\n
\n' 1 = Use Long FileNames when reading
\n' 0 = Don't use Long FileNames when reading
\nConst Sduselfn = 0
\n
\n' 1 = When using lfn, also support file name comparison
\n' 0 = When using lfn, don't support file name comparison
\nConst Sduselfncompare = 0
\n
\n' 1 = Use wipe
\n' 0 = Don't use wipe
\nConst Sdusewipe = 0
\n
\n' 1 = Use the size info routine
\n' 0 = Don't use the size info routine
\nConst Sdusesizeinfo = 0
\n
\n' 1 = Use the CRC7 function
\n' 0 = Don't use the CRC7 function
\nConst Sdusecrc7 = 0 ' This has no practical use in the library - use it if you want to add CRC7 checks yourself
\n
\n'===============================================================================
\n
\n' Sdstatus codes:
\n' 0 = Success (no error found)
\n' 1 = Timeout at initialization CMD0
\n' 2 = Timeout at initialization CMD8
\n' 3 = Timeout at initialization first CMD58
\n' 4 = Timeout at initialization CMD55 + ACMD41 loop
\n' 5 = Timeout at initialization second CMD58
\n' 6 = Timeout at CMD13
\n' 7 = Timeout while waiting for &H00 &HFE
\n' 8 = Minimum initialization detail unspecified error 1
\n' 9 = Minimum initialization detail unspecified error 2
\n' 10 = R1 idle (running initialization)
\n' 11 = R1 erase reset
\n' 12 = R1 illegal command
\n' 13 = R1 command CRC error
\n' 14 = R1 erase sequence error
\n' 15 = R1 address error
\n' 16 = R1 parameter error
\n' 17 = R3 not an SD card
\n' 18 = R3 supply voltage out of bounds
\n' 19 = R7 unsupported voltage or VHS error in CMD8 command
\n' 20 = R7 unspecified error in CMD8 response
\n' 21 = Unsupported FAT32 root cluster number (not 2)
\n' 22 = R3 card power up busy (OCR.31 = 0)
\n' 23 = Not supported file system
\n' 24 =
\n' 25 =
\n' 26 = A file entry has been found
\n' 27 = A directory entry has been found
\n' 28 = An available (previously erased) directory space has been found
\n' 29 = Unsupported number of sectors per cluster
\n' 30 =
\n' 31 = EOC End Of Cluster chain marker found
\n' 32 = EOD End Of Directory marker found
\n' 33 = Subdirectory . or .. entry found
\n' 34 = The volume ID has been found
\n' 35 = Unsupported sector size
\n' 36 = Long file name found
\n' 37 =
\n' 38 =
\n' 39 =
\n' 40 =
\n' 41 = Data rejected due to a CRC error
\n' 42 = Data rejected due to a Write Error
\n' 43 = Free FAT entry found
\n' 44 = End of FAT and no free entry found (partition full)
\n' 45 =
\n' 46 = We have searched the entire FAT16 root directory but not found what we were looking for
\n' 47 = Parent directory pointer found
\n' 48 = File or subdirectory found
\n
\n
\n' Status bits:
\n' Sdeof: 1 = EOF marker
\n' Sdreaddestination 0 = Sdbuffer, 1 = Sdfat1buffer
\n' Sdwriteorigin 0 = Sdbuffer, 1 = Sdfat1buffer
\n' Sdcreatemode 0 = file, 1 = subdirectory
\n' Sdclosefile 1 = close the current file
\n' Sdpartitionfull 1 = the partition is full (no more free FAT entries)
\n' Sdsavedatasector 1 = save the current data sector
\n' Sdfatcontinue 1 = continue looping through the current FAT sector
\n' Sddirlistdirection 0 = forward, 1 = backward
\n' Sddirliststartpoint 1 = the directory backward listing has reached the starting point
\n' Sddirlistendpoint 1 = the directory forward listing has reached the end point
\n' Sddirlistoutside 1 = we are outside of the directory cluster array when listing the directory
\n' Sdlfncontinue 1 = continuing assembling or printing the long filename
\n' Sdlfnfound 1 = last directory entry of a long filename found
\n' Sdappendcontinue 1 = continue comparing the filename
\n' Sdappendfound 1 = the file has been found
\n' Sderaseall 1 = erase all data sectors as well
\n
\n'===============================================================================
\n
\n' SPI declaration:
\n
\nConfig Portb.2 = Output ' The !SS pin can only be used as an output in SPI hardware master mode)
\nSd_cs Alias Portb.2
\n'Config Portb.5 = Output
\n'Sd_di Alias Portb.5 ' MOSI
\n
\n'Config Portb.7 = Output
\n'Sd_clk Alias Portb.7 ' Clock
\n
\n'Config Portb.6 = Input
\n'Sd_do Alias Portb.6 ' MISO
\n
\nConfig Portb.4 = Output
\nSd_di Alias Portb.4 ' MOSI
\n
\n Config Portb.5 = Output
\n Sd_clk Alias Portb.5 ' Clock
\n
\n Config Portb.3 = Input
\n Sd_do Alias Pinb.3 ' MISO
\n
\n' HW SPI - make sure that your initial clock frequency <= 400 kHz
\n' After initialization, try to increase the speed and also set the SPCR register to double speed
\nConfig Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 16 , Noss = 1 , Spiin = 255
\n'Spcr = &B010
\n '
\n
\nSpiinit ' Init SPI
\n
\n
\nDim Sdcommand As Byte ' The bytewise 8 to 48-bit command to SD
\nDim Sdresponse(6) As Byte ' The <= 48-bit response from SD
\nDim Sdstatus As Byte ' Status after gosub
\nDim Sdcardtype As Byte ' 1 = v1.x SDSC, 2 = v2+ SDSC, 3 = v2+ SDHC
\nDim Sdtempb As Byte ' Generic loop variables
\nDim Sdtempb2 As Byte
\nDim Sdtempb3 As Byte
\n
\nDim Sdtempwb(2) As Byte
\nDim Sdtempw As Word At Sdtempwb(1) Overlay
\n
\nDim Sdsectorb(4) As Byte
\nDim Sdsectord As Dword At Sdsectorb(1) Overlay ' Sector number for read/write
\n
\nDim Sdexpectedresponse As Byte ' The byte value we are waiting for after a CMD17
\n
\nDim Sdbuffer(512) As Byte ' The 512 byte array that is filled when reading data from SD
\n
\n
\n#if Sdfsactive = 1
\n
\n Const Sdbytespersecw = 512 ' The only supported sector size
\n
\n Dim Sdfattype As Byte ' FAT16 = 2 or FAT32 = 4 as derived from the partition type. FAT record = 2 bytes for FAT16 and 4 bytes for FAT32.
\n
\n #if Sdusewipe = 1
\n Dim Sdpartstart As Dword ' The absolute sector number for the partition start
\n
\n Dim Sdtotsecsb(4) As Byte
\n Dim Sdtotsecsd As Dword At Sdtotsecsb(1) Overlay ' The relative number of sectors in this partition (starting with Sdpartstart)
\n' Number of sectors in partition, including all 4 regions:
\n' 0 - Reserved Region
\n' 1 - FAT Region
\n' 2 - Root Directory Region (doesn't exist on FAT32 volumes)
\n' 3 - File and Directory Data Region
\n #endif
\n
\n ' Dim Sdfat32rootclusterb(4) As Byte
\n ' Dim Sdfat32rootclusterd As Dword At Sdfat32rootclusterb(1) Overlay ' Cluster number for the FAT32 root (normally 2 but could be higher (e.g. in case of bad cluster))
\n Const Sdfat32rootclusterd = 2
\n
\n Dim Sdfat1location As Dword ' FAT1 location (sector number)
\n Dim Sdfat2location As Dword ' FAT2 location (sector number)
\n
\n Dim Sdrootdirlocation As Dword ' FAT16 root dir location (sector number)
\n
\n Dim Sdsecsinroot As Word ' Number of sectors in FAT16 root dir
\n
\n Dim Sdsecspercluster As Byte ' Sectors per cluster
\n
\n Dim Sdsectorend As Word ' Assigned from Sdsecspercluster or Sdsecsinroot and serves as the final sector in the cluster or root
\n
\n Dim Sdsecincluster As Word ' Current sector number of the current cluster, 1 to Sdsecincluster (defined as word to have place for Sdsecsinroot)
\n
\n Dim Sddataareastart As Dword ' Sector number for start of data, cluster 2
\n
\n Dim Sdtempdb(4) As Byte
\n Dim Sdtempd As Dword At Sdtempdb(1) Overlay ' Generic loop/temp variable
\n
\n Dim Sdclusterb(4) As Byte
\n Dim Sdclusterd As Dword At Sdclusterb(1) Overlay ' Current cluster number
\n
\n Dim Sdbufferpos As Word ' Current buffer position, 1 to 512
\n
\n Dim Sdfilesizeb(4) As Byte
\n Dim Sdfilesized As Dword At Sdfilesizeb(1) Overlay ' File size in bytes
\n
\n Dim Sdbyterw As Byte ' The byte that is read or written
\n Dim Sdbytesread As Dword ' Counter for the number of read bytes
\n
\n#endif
\n
\n
\n
\n#if Sdusefsinfo = 1
\n
\n Dim Sdfat32fsinfolocationb(4) As Byte
\n Dim Sdfat32fsinfolocationw As Dword At Sdfat32fsinfolocationb(1) Overlay ' Sector number for the FAT32 fsinfo (Could probably use word - dword used for partition offset)
\n
\n Dim Sdfsinfofreeclustersb(4) As Byte
\n Dim Sdfsinfofreeclustersd As Dword At Sdfsinfofreeclustersb(1) Overlay ' Number of free clusters according to the FAT32 fsinfo
\n
\n Dim Sdfsinfonextfreeclusterb(4) As Byte
\n Dim Sdfsinfonextfreeclusterd As Dword At Sdfsinfonextfreeclusterb(1) Overlay ' Number of next free cluster according to the FAT32 fsinfo
\n
\n#endif
\n
\n#if Sdwmode = 1
\n Dim Sdfatbuffer(512) As Byte ' The 512 byte array that is filled when reading data from SD
\n#endif
\n
\n#if Sdwmode > 0 And Sdfsactive = 1
\n
\n Dim Sdpreviousclusterb(4) As Byte ' Previous cluster number
\n Dim Sdpreviousclusterd As Dword At Sdpreviousclusterb(1) Overlay
\n
\n Dim Sddirclusterb(4) As Byte
\n Dim Sddirclusterd As Dword At Sddirclusterb(1) Overlay ' Current directory cluster number
\n
\n Dim Sddirsecincluster As Word ' Chain start sector number of the current directory cluster, 1 to Sdsecincluster
\n Dim Sddirbufferpos As Word ' Chain start directory buffer position, 1 to 512
\n
\n Dim Sdwclusterb(4) As Byte ' The cluster number being written
\n Dim Sdwclusterd As Dword At Sdwclusterb(1) Overlay
\n
\n Dim Sdwsecincluster As Byte ' The sector number in the current cluster being written
\n
\n 'Dim Sdwbufferposb(2) As Byte
\n Dim Sdwbufferpos As Word 'At Sdwbufferposb(1) Overlay ' The byte number in the current sector being written
\n
\n Dim Sdwfilesizeb(4) As Byte
\n Dim Sdwfilesized As Dword At Sdwfilesizeb(1) Overlay ' Write file size in bytes
\n
\n Dim Sdfatclusterb(4) As Byte ' Stores the FAT1 entry's corresponding cluster number (not the pointer to the next entry)
\n Dim Sdfatclusterd As Dword At Sdfatclusterb(1) Overlay
\n
\n Dim Sdfatsectornum As Dword ' FAT1 absolute sector number - stores the current FAT sector number
\n Dim Sdfatbufferpos As Word ' Buffer position in Sdfatsector - stores the buffer position in the current FAT sector
\n
\n ' DateTime variables
\n Dim Sdday As Byte
\n Dim Sdmonth As Byte
\n Dim Sdyear As Word
\n Dim Sdmseconds As Byte
\n Dim Sdseconds As Byte
\n Dim Sdminutes As Byte
\n Dim Sdhours As Byte
\n
\n Dim Sddateb(2) As Byte ' Date variable for the directory entry DateTime
\n Dim Sddatew As Word At Sddateb(1) Overlay
\n
\n Dim Sdtimeb(2) As Byte ' Time variable for the directory entry DateTime
\n Dim Sdtimew As Word At Sdtimeb(1) Overlay
\n
\n#endif
\n
\n#if Sdusefind = 1
\n Dim Sddirectorymode As Byte ' 0 = find file, 1 = find subdirectory, 2 = find volume ID, 3 = find available directory entry, 4 = find parent directory, 5 = return entire entry unless EOD
\n #if Sdusefindstoreentry = 1
\n Dim Sdfinddirentry(32) As Byte ' An entire directory entry
\n #endif
\n#endif
\n
\n#if Sdusedirlist = 1 Or Sdwmode > 0
\n#if Sdfsactive = 1
\n Dim Sdstartdirclusterb(4) As Byte ' Directory chain start cluster number
\n Dim Sdstartdirclusterd As Dword At Sdstartdirclusterb(1) Overlay
\n#endif
\n#endif
\n
\n#if Sdusedirlist = 1 Or Sdusefind = 1
\n Dim Sdentrynames As String * 11 ' 8.3 file or subdirectory name without the dot
\n Dim Sdentrynameb(11) As Byte At Sdentrynames Overlay
\n#endif
\n
\n#if Sdusedirlist = 1
\n
\n Dim Sddirlistarray(sddirlistarraysize) As Dword ' The array
\n Dim Sddirlistarraypointer As Byte ' The pointer of where we are in the array of already found directory clusters (useful when going backwards and then forward)
\n 'Dim Sddirlistarraypointer As Word
\n Dim Sddirlistarraycounter As Byte ' Keeps track of how many clusters exist in the array
\n 'Dim Sddirlistarraycounter As Word
\n
\n Dim Sddirlistnextclusterb(4) As Byte ' Next or previous FAT cluster number
\n Dim Sddirlistnextclusterd As Dword At Sddirlistnextclusterb(1) Overlay
\n
\n Dim Sddirlistcurrclusterb(4) As Byte ' Current FAT cluster number
\n Dim Sddirlistcurrclusterd As Dword At Sddirlistcurrclusterb(1) Overlay
\n
\n Dim Sddirlistdirentry(32) As Byte ' Holds one directory entry at the time
\n
\n' Dim Sdtempw2 As Word ' Generic temp/loop variable (used in the example code)
\n
\n#endif
\n
\n#if Sduselfn = 1
\n
\n Dim Sdlfns As String * 255 ' Return variable for the long filename
\n Dim Sdlfnb(255) As Byte At Sdlfns Overlay
\n
\n Dim Sdlfnchecksum As Byte ' 8.3 filename checksum
\n Dim Sdtempb4 As Byte ' Generic loop / temp variable
\n Dim Sdlfndirentry(32) As Byte ' Holds one directory entry at the time
\n
\n #if Sduselfncompare = 1
\n Dim Sdlfn2s As String * 255 ' Compare variable for the long filename
\n Dim Sdlfn2b(255) As Byte At Sdlfn2s Overlay
\n #endif
\n
\n#endif
\n
\n#if Sdusesizeinfo = 1
\n Dim Sdcsize As Long
\n Dim Sdcsizemult As Byte
\n Dim Sdreadbllen As Byte
\n#endif
\n
\n#if Sdusecrc7 = 1
\n Declare Function Sdcrc7(byval Sdarray As Byte) As Byte
\n Dim Sdcrc7byte As Byte
\n#endif
\n
\n#if Sdwmode > 0 And Sdfsactive = 1
\n Dim Sdcreatemode As Bit ' 0 = file, 1 = subdirectory
\n Dim Sdclosefile As Bit ' 1 = close the current file
\n Dim Sdpartitionfull As Bit ' 1 = the partition is full (no more free FAT entries)
\n Dim Sdsavedatasector As Bit ' 1 = save the current data sector
\n Dim Sdfatcontinue As Bit ' 1 = continue looping through the current FAT sector
\n#endif
\n
\n#if Sdwmode = 1 And Sdfsactive = 1
\n Dim Sdreaddestination As Bit ' 0 = Sdbuffer, 1 = Sdfat1buffer
\n Dim Sdwriteorigin As Bit ' 0 = Sdbuffer, 1 = Sdfat1buffer
\n#endif
\n
\n#if Sdrmode = 1
\n Dim Sdeof As Bit ' EOF marker
\n#endif
\n
\n#if Sdusedirlist = 1
\n Dim Sddirliststartpoint As Bit ' 1 = the directory backward listing has reached the starting point
\n Dim Sddirlistendpoint As Bit ' 1 = the directory forward listing has reached the end point
\n Dim Sddirlistdirection As Bit ' 0 = forward, 1 = backward
\n Dim Sddirlistoutside As Bit ' 1 = we have scrolled outside of Sddirlistarray() array
\n #if Sduseappend = 1
\n Dim Sdappendcontinue As Bit ' 1 = continue comparing the filename
\n Dim Sdappendfound As Bit ' 1 = the file has been found
\n #endif
\n#endif
\n
\n#if Sduselfn = 1
\n Dim Sdlfncontinue As Bit ' 1 = continuing assembling the long filename
\n Dim Sdlfnfound As Bit ' 1 = last directory entry of a long filename found
\n#endif
\n
\n#if Sdusewipe = 1
\n Dim Sderaseall As Bit ' 1 = erase all data sectors as well
\n#endif[/code]
\n
\nPaulo