From 208edeee0f97a56697f0b15b519a9e723436f007 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Wed, 30 Dec 2009 09:00:29 +0000 Subject: Add new TemperatureDataLogger project, a simple USB Mass Storage class Temperature Data Logger using the onboard Dataflash and Temperature sensor. --- LUFA.pnproj | 2 +- LUFA/Drivers/Peripheral/AVRU4U6U7/ADC.h | 2 +- LUFA/ManPages/ChangeLog.txt | 3 + LUFA/ManPages/LibraryApps.txt | 1 + .../StandaloneProgrammer/Lib/DataflashManager.c | 2 +- .../StandaloneProgrammer/Lib/DataflashManager.h | 2 +- Projects/TemperatureDataLogger/Descriptors.c | 217 + Projects/TemperatureDataLogger/Descriptors.h | 72 + Projects/TemperatureDataLogger/Doxygen.conf | 1485 +++++ .../TemperatureDataLogger/Lib/DataflashManager.c | 525 ++ .../TemperatureDataLogger/Lib/DataflashManager.h | 81 + .../TemperatureDataLogger/Lib/FATFs/00readme.txt | 110 + Projects/TemperatureDataLogger/Lib/FATFs/diskio.c | 87 + Projects/TemperatureDataLogger/Lib/FATFs/diskio.h | 71 + .../TemperatureDataLogger/Lib/FATFs/diskio.lst | 149 + Projects/TemperatureDataLogger/Lib/FATFs/ff.c | 3153 +++++++++ Projects/TemperatureDataLogger/Lib/FATFs/ff.h | 596 ++ Projects/TemperatureDataLogger/Lib/FATFs/ff.lst | 6864 ++++++++++++++++++++ Projects/TemperatureDataLogger/Lib/FATFs/ffconf.h | 166 + Projects/TemperatureDataLogger/Lib/FATFs/integer.h | 37 + Projects/TemperatureDataLogger/Lib/SCSI.c | 281 + Projects/TemperatureDataLogger/Lib/SCSI.h | 86 + Projects/TemperatureDataLogger/Lib/SCSI.lst | 734 +++ Projects/TemperatureDataLogger/TempDataLogger.c | 187 + Projects/TemperatureDataLogger/TempDataLogger.h | 89 + .../TemperatureDataLogger.txt | 83 + Projects/TemperatureDataLogger/makefile | 748 +++ Projects/makefile | 4 + 28 files changed, 15833 insertions(+), 4 deletions(-) create mode 100644 Projects/TemperatureDataLogger/Descriptors.c create mode 100644 Projects/TemperatureDataLogger/Descriptors.h create mode 100644 Projects/TemperatureDataLogger/Doxygen.conf create mode 100644 Projects/TemperatureDataLogger/Lib/DataflashManager.c create mode 100644 Projects/TemperatureDataLogger/Lib/DataflashManager.h create mode 100644 Projects/TemperatureDataLogger/Lib/FATFs/00readme.txt create mode 100644 Projects/TemperatureDataLogger/Lib/FATFs/diskio.c create mode 100644 Projects/TemperatureDataLogger/Lib/FATFs/diskio.h create mode 100644 Projects/TemperatureDataLogger/Lib/FATFs/diskio.lst create mode 100644 Projects/TemperatureDataLogger/Lib/FATFs/ff.c create mode 100644 Projects/TemperatureDataLogger/Lib/FATFs/ff.h create mode 100644 Projects/TemperatureDataLogger/Lib/FATFs/ff.lst create mode 100644 Projects/TemperatureDataLogger/Lib/FATFs/ffconf.h create mode 100644 Projects/TemperatureDataLogger/Lib/FATFs/integer.h create mode 100644 Projects/TemperatureDataLogger/Lib/SCSI.c create mode 100644 Projects/TemperatureDataLogger/Lib/SCSI.h create mode 100644 Projects/TemperatureDataLogger/Lib/SCSI.lst create mode 100644 Projects/TemperatureDataLogger/TempDataLogger.c create mode 100644 Projects/TemperatureDataLogger/TempDataLogger.h create mode 100644 Projects/TemperatureDataLogger/TemperatureDataLogger.txt create mode 100644 Projects/TemperatureDataLogger/makefile diff --git a/LUFA.pnproj b/LUFA.pnproj index 8b3079153..71abf210f 100644 --- a/LUFA.pnproj +++ b/LUFA.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/LUFA/Drivers/Peripheral/AVRU4U6U7/ADC.h b/LUFA/Drivers/Peripheral/AVRU4U6U7/ADC.h index 90fb4a35f..17d6c5e9f 100644 --- a/LUFA/Drivers/Peripheral/AVRU4U6U7/ADC.h +++ b/LUFA/Drivers/Peripheral/AVRU4U6U7/ADC.h @@ -149,7 +149,7 @@ #define ADC_GetStatus() ((ADCSRA & (1 << ADEN)) ? true : false) - #define ADC_IsReadingComplete() (!(ADCSRA & (1 << ADSC))) + #define ADC_IsReadingComplete() (ADCSRA & (1 << ADSC)) #define ADC_GetResult() ADC #endif diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index c206ad04d..a64428e8b 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -12,6 +12,8 @@ * - Added TPI programming support for 6-pin ATTINY to the AVRISP programmer project * - Added command timeout counter to the AVRISP project so that the device no longer freezes when incorrectly connected * to a target + * - Added new TemperatureDataLogger application, a USB data logger which writes to the device's dataflash and appears to + * the host as a standard Mass Storage device when inserted * * Changed: * - Slowed down bit-banged PDI programming in the AVRISP project slightly to prevent transmission errors @@ -22,6 +24,7 @@ * Fixed: * - Fixed AVRISP project not able to enter programming mode when ISP protocol is used * - Fixed AVRISP PDI race condition where the guard time between direction changes could be interpreted as a start bit + * - Fixed ADC_IsReadingComplete() returning an inverted result * * \section Sec_ChangeLog091223 Version 091223 * diff --git a/LUFA/ManPages/LibraryApps.txt b/LUFA/ManPages/LibraryApps.txt index 0ea01c7dc..c79463ef5 100644 --- a/LUFA/ManPages/LibraryApps.txt +++ b/LUFA/ManPages/LibraryApps.txt @@ -103,6 +103,7 @@ * - LEDNotifier - USB LED Notification project * - Magstripe - Magnetic Stripe Card Reader project * - MissileLaucher - Toy Missile Launcher Host project + * - TemperatureDataLogger - Temperature Datalogging project * - USBtoSerial - USB to USART Serial Converter project * * diff --git a/Projects/Incomplete/StandaloneProgrammer/Lib/DataflashManager.c b/Projects/Incomplete/StandaloneProgrammer/Lib/DataflashManager.c index 8de1573db..8771fca53 100644 --- a/Projects/Incomplete/StandaloneProgrammer/Lib/DataflashManager.c +++ b/Projects/Incomplete/StandaloneProgrammer/Lib/DataflashManager.c @@ -290,7 +290,7 @@ void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, con * \param[in] TotalBlocks Number of blocks of data to write * \param[in] BufferPtr Pointer to the data source RAM buffer */ -void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr) +void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, const uint8_t* BufferPtr) { uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); diff --git a/Projects/Incomplete/StandaloneProgrammer/Lib/DataflashManager.h b/Projects/Incomplete/StandaloneProgrammer/Lib/DataflashManager.h index d77c5cea0..555cd04e3 100644 --- a/Projects/Incomplete/StandaloneProgrammer/Lib/DataflashManager.h +++ b/Projects/Incomplete/StandaloneProgrammer/Lib/DataflashManager.h @@ -72,7 +72,7 @@ void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks); void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, - uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3); + const uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3); void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3); void DataflashManager_ResetDataflashProtections(void); diff --git a/Projects/TemperatureDataLogger/Descriptors.c b/Projects/TemperatureDataLogger/Descriptors.c new file mode 100644 index 000000000..75bf974ff --- /dev/null +++ b/Projects/TemperatureDataLogger/Descriptors.c @@ -0,0 +1,217 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2009. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * USB Device Descriptors, for library use when in USB device mode. Descriptors are special + * computer-readable structures which the host requests upon device enumeration, to determine + * the device's capabilities and functions. + */ + +#include "Descriptors.h" + +/* On some devices, there is a factory set internal serial number which can be automatically sent to the host as + * the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL. + * This allows the host to track a device across insertions on different ports, allowing them to retain allocated + * resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices + * so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value + * from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and + * port location). + */ +#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR) + #warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor. +#endif + +/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall + * device characteristics, including the supported USB version, control endpoint size and the + * number of device configurations. The descriptor is read out by the USB host when the enumeration + * process begins. + */ +USB_Descriptor_Device_t PROGMEM DeviceDescriptor = +{ + .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, + + .USBSpecification = VERSION_BCD(01.10), + .Class = 0x00, + .SubClass = 0x00, + .Protocol = 0x00, + + .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, + + .VendorID = 0x03EB, + .ProductID = 0x2045, + .ReleaseNumber = 0x0000, + + .ManufacturerStrIndex = 0x01, + .ProductStrIndex = 0x02, + .SerialNumStrIndex = USE_INTERNAL_SERIAL, + + .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS +}; + +/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage + * of the device in one of its supported configurations, including information about any device interfaces + * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting + * a configuration so that the host may correctly communicate with the USB device. + */ +USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = +{ + .Config = + { + .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, + + .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), + .TotalInterfaces = 1, + + .ConfigurationNumber = 1, + .ConfigurationStrIndex = NO_DESCRIPTOR, + + .ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED, + + .MaxPowerConsumption = USB_CONFIG_POWER_MA(100) + }, + + .Interface = + { + .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, + + .InterfaceNumber = 0, + .AlternateSetting = 0, + + .TotalEndpoints = 2, + + .Class = 0x08, + .SubClass = 0x06, + .Protocol = 0x50, + + .InterfaceStrIndex = NO_DESCRIPTOR + }, + + .DataInEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MASS_STORAGE_IN_EPNUM), + .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = MASS_STORAGE_IO_EPSIZE, + .PollingIntervalMS = 0x00 + }, + + .DataOutEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | MASS_STORAGE_OUT_EPNUM), + .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = MASS_STORAGE_IO_EPSIZE, + .PollingIntervalMS = 0x00 + } +}; + +/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests + * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate + * via the language ID table available at USB.org what languages the device supports for its string descriptors. + */ +USB_Descriptor_String_t PROGMEM LanguageString = +{ + .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, + + .UnicodeString = {LANGUAGE_ID_ENG} +}; + +/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable + * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device + * Descriptor. + */ +USB_Descriptor_String_t PROGMEM ManufacturerString = +{ + .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, + + .UnicodeString = L"Dean Camera" +}; + +/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, + * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device + * Descriptor. + */ +USB_Descriptor_String_t PROGMEM ProductString = +{ + .Header = {.Size = USB_STRING_LEN(22), .Type = DTYPE_String}, + + .UnicodeString = L"LUFA Mass Storage Demo" +}; + +/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" + * documentation) by the application code so that the address and size of a requested descriptor can be given + * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function + * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the + * USB host. + */ +uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) +{ + const uint8_t DescriptorType = (wValue >> 8); + const uint8_t DescriptorNumber = (wValue & 0xFF); + + void* Address = NULL; + uint16_t Size = NO_DESCRIPTOR; + + switch (DescriptorType) + { + case DTYPE_Device: + Address = (void*)&DeviceDescriptor; + Size = sizeof(USB_Descriptor_Device_t); + break; + case DTYPE_Configuration: + Address = (void*)&ConfigurationDescriptor; + Size = sizeof(USB_Descriptor_Configuration_t); + break; + case DTYPE_String: + switch (DescriptorNumber) + { + case 0x00: + Address = (void*)&LanguageString; + Size = pgm_read_byte(&LanguageString.Header.Size); + break; + case 0x01: + Address = (void*)&ManufacturerString; + Size = pgm_read_byte(&ManufacturerString.Header.Size); + break; + case 0x02: + Address = (void*)&ProductString; + Size = pgm_read_byte(&ProductString.Header.Size); + break; + } + + break; + } + + *DescriptorAddress = Address; + return Size; +} diff --git a/Projects/TemperatureDataLogger/Descriptors.h b/Projects/TemperatureDataLogger/Descriptors.h new file mode 100644 index 000000000..7df21e619 --- /dev/null +++ b/Projects/TemperatureDataLogger/Descriptors.h @@ -0,0 +1,72 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2009. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Header file for Descriptors.c. + */ + +#ifndef _DESCRIPTORS_H_ +#define _DESCRIPTORS_H_ + + /* Includes: */ + #include + + #include + #include + + /* Macros: */ + /** Endpoint number of the Mass Storage device-to-host data IN endpoint. */ + #define MASS_STORAGE_IN_EPNUM 3 + + /** Endpoint number of the Mass Storage host-to-device data OUT endpoint. */ + #define MASS_STORAGE_OUT_EPNUM 4 + + /** Size in bytes of the Mass Storage data endpoints. */ + #define MASS_STORAGE_IO_EPSIZE 64 + + /* Type Defines: */ + /** Type define for the device configuration descriptor structure. This must be defined in the + * application code, as the configuration descriptor contains several sub-descriptors which + * vary between devices, and which describe the device's usage to the host. + */ + typedef struct + { + USB_Descriptor_Configuration_Header_t Config; + USB_Descriptor_Interface_t Interface; + USB_Descriptor_Endpoint_t DataInEndpoint; + USB_Descriptor_Endpoint_t DataOutEndpoint; + } USB_Descriptor_Configuration_t; + + /* Function Prototypes: */ + uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); + +#endif diff --git a/Projects/TemperatureDataLogger/Doxygen.conf b/Projects/TemperatureDataLogger/Doxygen.conf new file mode 100644 index 000000000..f48af7f0b --- /dev/null +++ b/Projects/TemperatureDataLogger/Doxygen.conf @@ -0,0 +1,1485 @@ +# Doxyfile 1.5.7.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "Temperature Datalogger Project" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.0.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = ./Documentation/ + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, +# Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = NO + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = NO + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ./ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.h \ + *.c \ + *.txt + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = Documentation/ + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = */LowLevel/USBMode.h + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = __* + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = NO + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = YES + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = YES + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# Qt Help Project / Namespace. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# Qt Help Project / Virtual Folders. + +QHP_VIRTUAL_FOLDER = doc + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file . + +QHG_LOCATION = + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 1 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to FRAME, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. Other possible values +# for this tag are: HIERARCHIES, which will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list; +# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which +# disables this behavior completely. For backwards compatibility with previous +# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE +# respectively. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = __DOXYGEN__ + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = BUTTLOADTAG + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = NO + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = NO + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = NO + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = NO + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = NO + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 15 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 2 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/Projects/TemperatureDataLogger/Lib/DataflashManager.c b/Projects/TemperatureDataLogger/Lib/DataflashManager.c new file mode 100644 index 000000000..38a54a17b --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/DataflashManager.c @@ -0,0 +1,525 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2009. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Functions to manage the physical dataflash media, including reading and writing of + * blocks of data. These functions are called by the SCSI layer when data must be stored + * or retrieved to/from the physical storage media. If a different media is used (such + * as a SD card or EEPROM), functions similar to these will need to be generated. + */ + +#define INCLUDE_FROM_DATAFLASHMANAGER_C +#include "DataflashManager.h" + +/** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board dataflash IC(s), from + * the pre-selected data OUT endpoint. This routine reads in OS sized blocks from the endpoint and writes + * them to the dataflash in Dataflash page sized blocks. + * + * \param[in] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state + * \param[in] BlockAddress Data block starting address for the write sequence + * \param[in] TotalBlocks Number of blocks of data to write + */ +void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks) +{ + uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); + uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); + uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); + bool UsingSecondBuffer = false; + + /* Select the correct starting Dataflash IC for the block requested */ + Dataflash_SelectChipFromPage(CurrDFPage); + +#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) + /* Copy selected dataflash's current page contents to the dataflash buffer */ + Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); + Dataflash_SendAddressBytes(CurrDFPage, 0); + Dataflash_WaitWhileBusy(); +#endif + + /* Send the dataflash buffer write command */ + Dataflash_SendByte(DF_CMD_BUFF1WRITE); + Dataflash_SendAddressBytes(0, CurrDFPageByte); + + /* Wait until endpoint is ready before continuing */ + if (Endpoint_WaitUntilReady()) + return; + + while (TotalBlocks) + { + uint8_t BytesInBlockDiv16 = 0; + + /* Write an endpoint packet sized data block to the dataflash */ + while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) + { + /* Check if the endpoint is currently empty */ + if (!(Endpoint_IsReadWriteAllowed())) + { + /* Clear the current endpoint bank */ + Endpoint_ClearOUT(); + + /* Wait until the host has sent another packet */ + if (Endpoint_WaitUntilReady()) + return; + } + + /* Check if end of dataflash page reached */ + if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) + { + /* Write the dataflash buffer contents back to the dataflash page */ + Dataflash_WaitWhileBusy(); + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE); + Dataflash_SendAddressBytes(CurrDFPage, 0); + + /* Reset the dataflash buffer counter, increment the page counter */ + CurrDFPageByteDiv16 = 0; + CurrDFPage++; + + /* Once all the dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */ + if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS)) + UsingSecondBuffer = !(UsingSecondBuffer); + + /* Select the next dataflash chip based on the new dataflash page index */ + Dataflash_SelectChipFromPage(CurrDFPage); + +#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) + /* If less than one dataflash page remaining, copy over the existing page to preserve trailing data */ + if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4)) + { + /* Copy selected dataflash's current page contents to the dataflash buffer */ + Dataflash_WaitWhileBusy(); + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1); + Dataflash_SendAddressBytes(CurrDFPage, 0); + Dataflash_WaitWhileBusy(); + } +#endif + + /* Send the dataflash buffer write command */ + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE); + Dataflash_SendAddressBytes(0, 0); + } + + /* Write one 16-byte chunk of data to the dataflash */ + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + Dataflash_SendByte(Endpoint_Read_Byte()); + + /* Increment the dataflash page 16 byte block counter */ + CurrDFPageByteDiv16++; + + /* Increment the block 16 byte block counter */ + BytesInBlockDiv16++; + + /* Check if the current command is being aborted by the host */ + if (MSInterfaceInfo->State.IsMassStoreReset) + return; + } + + /* Decrement the blocks remaining counter and reset the sub block counter */ + TotalBlocks--; + } + + /* Write the dataflash buffer contents back to the dataflash page */ + Dataflash_WaitWhileBusy(); + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE); + Dataflash_SendAddressBytes(CurrDFPage, 0x00); + Dataflash_WaitWhileBusy(); + + /* If the endpoint is empty, clear it ready for the next packet from the host */ + if (!(Endpoint_IsReadWriteAllowed())) + Endpoint_ClearOUT(); + + /* Deselect all dataflash chips */ + Dataflash_DeselectChip(); +} + +/** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board dataflash IC(s), into + * the pre-selected data IN endpoint. This routine reads in Dataflash page sized blocks from the Dataflash + * and writes them in OS sized blocks to the endpoint. + * + * \param[in] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state + * \param[in] BlockAddress Data block starting address for the read sequence + * \param[in] TotalBlocks Number of blocks of data to read + */ +void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks) +{ + uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); + uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); + uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); + + /* Select the correct starting Dataflash IC for the block requested */ + Dataflash_SelectChipFromPage(CurrDFPage); + + /* Send the dataflash main memory page read command */ + Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD); + Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte); + Dataflash_SendByte(0x00); + Dataflash_SendByte(0x00); + Dataflash_SendByte(0x00); + Dataflash_SendByte(0x00); + + /* Wait until endpoint is ready before continuing */ + if (Endpoint_WaitUntilReady()) + return; + + while (TotalBlocks) + { + uint8_t BytesInBlockDiv16 = 0; + + /* Write an endpoint packet sized data block to the dataflash */ + while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) + { + /* Check if the endpoint is currently full */ + if (!(Endpoint_IsReadWriteAllowed())) + { + /* Clear the endpoint bank to send its contents to the host */ + Endpoint_ClearIN(); + + /* Wait until the endpoint is ready for more data */ + if (Endpoint_WaitUntilReady()) + return; + } + + /* Check if end of dataflash page reached */ + if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) + { + /* Reset the dataflash buffer counter, increment the page counter */ + CurrDFPageByteDiv16 = 0; + CurrDFPage++; + + /* Select the next dataflash chip based on the new dataflash page index */ + Dataflash_SelectChipFromPage(CurrDFPage); + + /* Send the dataflash main memory page read command */ + Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD); + Dataflash_SendAddressBytes(CurrDFPage, 0); + Dataflash_SendByte(0x00); + Dataflash_SendByte(0x00); + Dataflash_SendByte(0x00); + Dataflash_SendByte(0x00); + } + + /* Read one 16-byte chunk of data from the dataflash */ + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + Endpoint_Write_Byte(Dataflash_ReceiveByte()); + + /* Increment the dataflash page 16 byte block counter */ + CurrDFPageByteDiv16++; + + /* Increment the block 16 byte block counter */ + BytesInBlockDiv16++; + + /* Check if the current command is being aborted by the host */ + if (MSInterfaceInfo->State.IsMassStoreReset) + return; + } + + /* Decrement the blocks remaining counter */ + TotalBlocks--; + } + + /* If the endpoint is full, send its contents to the host */ + if (!(Endpoint_IsReadWriteAllowed())) + Endpoint_ClearIN(); + + /* Deselect all dataflash chips */ + Dataflash_DeselectChip(); +} + +/** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board dataflash IC(s), from + * the a given RAM buffer. This routine reads in OS sized blocks from the buffer and writes them to the + * dataflash in Dataflash page sized blocks. This can be linked to FAT libraries to write files to the + * dataflash. + * + * \param[in] BlockAddress Data block starting address for the write sequence + * \param[in] TotalBlocks Number of blocks of data to write + * \param[in] BufferPtr Pointer to the data source RAM buffer + */ +void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, const uint8_t* BufferPtr) +{ + uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); + uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); + uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); + bool UsingSecondBuffer = false; + + /* Select the correct starting Dataflash IC for the block requested */ + Dataflash_SelectChipFromPage(CurrDFPage); + +#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) + /* Copy selected dataflash's current page contents to the dataflash buffer */ + Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); + Dataflash_SendAddressBytes(CurrDFPage, 0); + Dataflash_WaitWhileBusy(); +#endif + + /* Send the dataflash buffer write command */ + Dataflash_SendByte(DF_CMD_BUFF1WRITE); + Dataflash_SendAddressBytes(0, CurrDFPageByte); + + while (TotalBlocks) + { + uint8_t BytesInBlockDiv16 = 0; + + /* Write an endpoint packet sized data block to the dataflash */ + while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) + { + /* Check if end of dataflash page reached */ + if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) + { + /* Write the dataflash buffer contents back to the dataflash page */ + Dataflash_WaitWhileBusy(); + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE); + Dataflash_SendAddressBytes(CurrDFPage, 0); + + /* Reset the dataflash buffer counter, increment the page counter */ + CurrDFPageByteDiv16 = 0; + CurrDFPage++; + + /* Once all the dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */ + if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS)) + UsingSecondBuffer = !(UsingSecondBuffer); + + /* Select the next dataflash chip based on the new dataflash page index */ + Dataflash_SelectChipFromPage(CurrDFPage); + +#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) + /* If less than one dataflash page remaining, copy over the existing page to preserve trailing data */ + if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4)) + { + /* Copy selected dataflash's current page contents to the dataflash buffer */ + Dataflash_WaitWhileBusy(); + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1); + Dataflash_SendAddressBytes(CurrDFPage, 0); + Dataflash_WaitWhileBusy(); + } +#endif + + /* Send the dataflash buffer write command */ + Dataflash_ToggleSelectedChipCS(); + Dataflash_SendByte(DF_CMD_BUFF1WRITE); + Dataflash_SendAddressBytes(0, 0); + } + + /* Write one 16-byte chunk of data to the dataflash */ + for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++) + Dataflash_SendByte(*(BufferPtr++)); + + /* Increment the dataflash page 16 byte block counter */ + CurrDFPageByteDiv16++; + + /* Increment the block 16 byte block counter */ + BytesInBlockDiv16++; + } + + /* Decrement the blocks remaining counter and reset the sub block counter */ + TotalBlocks--; + } + + /* Write the dataflash buffer contents back to the dataflash page */ + Dataflash_WaitWhileBusy(); + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE); + Dataflash_SendAddressBytes(CurrDFPage, 0x00); + Dataflash_WaitWhileBusy(); + + /* Deselect all dataflash chips */ + Dataflash_DeselectChip(); +} + +/** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board dataflash IC(s), into + * the a preallocated RAM buffer. This routine reads in Dataflash page sized blocks from the Dataflash + * and writes them in OS sized blocks to the given buffer. This can be linked to FAT libraries to read + * the files stored on the dataflash. + * + * \param[in] BlockAddress Data block starting address for the read sequence + * \param[in] TotalBlocks Number of blocks of data to read + * \param[out] BufferPtr Pointer to the data destination RAM buffer + */ +void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr) +{ + uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); + uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); + uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); + + /* Select the correct starting Dataflash IC for the block requested */ + Dataflash_SelectChipFromPage(CurrDFPage); + + /* Send the dataflash main memory page read command */ + Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD); + Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte); + Dataflash_SendByte(0x00); + Dataflash_SendByte(0x00); + Dataflash_SendByte(0x00); + Dataflash_SendByte(0x00); + + while (TotalBlocks) + { + uint8_t BytesInBlockDiv16 = 0; + + /* Write an endpoint packet sized data block to the dataflash */ + while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) + { + /* Check if end of dataflash page reached */ + if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) + { + /* Reset the dataflash buffer counter, increment the page counter */ + CurrDFPageByteDiv16 = 0; + CurrDFPage++; + + /* Select the next dataflash chip based on the new dataflash page index */ + Dataflash_SelectChipFromPage(CurrDFPage); + + /* Send the dataflash main memory page read command */ + Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD); + Dataflash_SendAddressBytes(CurrDFPage, 0); + Dataflash_SendByte(0x00); + Dataflash_SendByte(0x00); + Dataflash_SendByte(0x00); + Dataflash_SendByte(0x00); + } + + /* Read one 16-byte chunk of data from the dataflash */ + for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++) + *(BufferPtr++) = Dataflash_ReceiveByte(); + + /* Increment the dataflash page 16 byte block counter */ + CurrDFPageByteDiv16++; + + /* Increment the block 16 byte block counter */ + BytesInBlockDiv16++; + } + + /* Decrement the blocks remaining counter */ + TotalBlocks--; + } + + /* Deselect all dataflash chips */ + Dataflash_DeselectChip(); +} + +/** Disables the dataflash memory write protection bits on the board Dataflash ICs, if enabled. */ +void DataflashManager_ResetDataflashProtections(void) +{ + /* Select first dataflash chip, send the read status register command */ + Dataflash_SelectChip(DATAFLASH_CHIP1); + Dataflash_SendByte(DF_CMD_GETSTATUS); + + /* Check if sector protection is enabled */ + if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON) + { + Dataflash_ToggleSelectedChipCS(); + + /* Send the commands to disable sector protection */ + Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]); + Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]); + Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]); + Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]); + } + + /* Select second dataflash chip (if present on selected board), send read status register command */ + #if (DATAFLASH_TOTALCHIPS == 2) + Dataflash_SelectChip(DATAFLASH_CHIP2); + Dataflash_SendByte(DF_CMD_GETSTATUS); + + /* Check if sector protection is enabled */ + if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON) + { + Dataflash_ToggleSelectedChipCS(); + + /* Send the commands to disable sector protection */ + Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]); + Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]); + Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]); + Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]); + } + #endif + + /* Deselect current dataflash chip */ + Dataflash_DeselectChip(); +} + +/** Performs a simple test on the attached Dataflash IC(s) to ensure that they are working. + * + * \return Boolean true if all media chips are working, false otherwise + */ +bool DataflashManager_CheckDataflashOperation(void) +{ + uint8_t ReturnByte; + + /* Test first Dataflash IC is present and responding to commands */ + Dataflash_SelectChip(DATAFLASH_CHIP1); + Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO); + ReturnByte = Dataflash_ReceiveByte(); + Dataflash_DeselectChip(); + + /* If returned data is invalid, fail the command */ + if (ReturnByte != DF_MANUFACTURER_ATMEL) + return false; + + #if (DATAFLASH_TOTALCHIPS == 2) + /* Test second Dataflash IC is present and responding to commands */ + Dataflash_SelectChip(DATAFLASH_CHIP2); + Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO); + ReturnByte = Dataflash_ReceiveByte(); + Dataflash_DeselectChip(); + + /* If returned data is invalid, fail the command */ + if (ReturnByte != DF_MANUFACTURER_ATMEL) + return false; + #endif + + return true; +} diff --git a/Projects/TemperatureDataLogger/Lib/DataflashManager.h b/Projects/TemperatureDataLogger/Lib/DataflashManager.h new file mode 100644 index 000000000..c6256fab6 --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/DataflashManager.h @@ -0,0 +1,81 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2009. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Header file for DataflashManager.c. + */ + +#ifndef _DATAFLASH_MANAGER_H +#define _DATAFLASH_MANAGER_H + + /* Includes: */ + #include + + #include "TempDataLogger.h" + #include "Descriptors.h" + + #include + #include + #include + #include + + /* Preprocessor Checks: */ + #if (DATAFLASH_PAGE_SIZE % 16) + #error Dataflash page size must be a multiple of 16 bytes. + #endif + + /* Defines: */ + /** Total number of bytes of the storage medium, comprised of one or more dataflash ICs. */ + #define VIRTUAL_MEMORY_BYTES ((uint32_t)DATAFLASH_PAGES * DATAFLASH_PAGE_SIZE * DATAFLASH_TOTALCHIPS) + + /** Block size of the device. This is kept at 512 to remain compatible with the OS despite the underlying + * storage media (Dataflash) using a different native block size. Do not change this value. + */ + #define VIRTUAL_MEMORY_BLOCK_SIZE 512 + + /** Total number of blocks of the virtual memory for reporting to the host as the device's total capacity. Do not + * change this value; change VIRTUAL_MEMORY_BYTES instead to alter the media size. + */ + #define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE) + + /* Function Prototypes: */ + void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, + uint16_t TotalBlocks); + void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, + uint16_t TotalBlocks); + void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, + const uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3); + void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, + uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3); + void DataflashManager_ResetDataflashProtections(void); + bool DataflashManager_CheckDataflashOperation(void); + +#endif diff --git a/Projects/TemperatureDataLogger/Lib/FATFs/00readme.txt b/Projects/TemperatureDataLogger/Lib/FATFs/00readme.txt new file mode 100644 index 000000000..c46a0fa1a --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/FATFs/00readme.txt @@ -0,0 +1,110 @@ +FatFs Module Source Files R0.07e (C)ChaN, 2009 + + +FILES + + ffconf.h Configuration file for FatFs module. + ff.h Common include file for FatFs and application module. + ff.c FatFs module. + diskio.h Common include file for FatFs and disk I/O module. + diskio.c Skeleton of low level disk I/O module. + integer.h Alternative type definitions for integer variables. + option Optional external functions. + + Low level disk I/O module is not included in this archive because the FatFs + module is only a generic file system layer and not depend on any specific + storage device. You have to provide a low level disk I/O module that written + to control your storage device. + + + +AGREEMENTS + + FatFs module is an open source software to implement FAT file system to + small embedded systems. This is a free software and is opened for education, + research and commercial developments under license policy of following trems. + + Copyright (C) 2009, ChaN, all right reserved. + + * The FatFs module is a free software and there is NO WARRANTY. + * No restriction on use. You can use, modify and redistribute it for + personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. + * Redistributions of source code must retain the above copyright notice. + + + +REVISION HISTORY + + Feb 26, 2006 R0.00 Prototype + + Apr 29, 2006 R0.01 First release. + + Jun 01, 2006 R0.02 Added FAT12. + Removed unbuffered mode. + Fixed a problem on small (<32M) patition. + + Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM. + + Sep 22, 2006 R0.03 Added f_rename. + Changed option _FS_MINIMUM to _FS_MINIMIZE. + + Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast. + Fixed f_mkdir creates incorrect directory on FAT32. + + Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs) + Changed some APIs for multiple drive system. + Added f_mkfs. (FatFs) + Added _USE_FAT32 option. (Tiny-FatFs) + + Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs) + Fixed an endian sensitive code in f_mkfs. (FatFs) + Added a capability of extending the file size to f_lseek. + Added minimization level 3. + Fixed a problem that can collapse a sector when recreate an + existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs) + + May 05, 2007 R0.04b Added _USE_NTFLAG option. + Added FSInfo support. + Fixed some problems corresponds to FAT32. (Tiny-FatFs) + Fixed DBCS name can result FR_INVALID_NAME. + Fixed short seek (0 < ofs <= csize) collapses the file object. + + Aug 25, 2007 R0.05 Changed arguments of f_read, f_write. + Changed arguments of f_mkfs. (FatFs) + Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs) + Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs) + + Feb 03, 2008 R0.05a Added f_truncate(). + Added f_utime(). + Fixed off by one error at FAT sub-type determination. + Fixed btr in f_read() can be mistruncated. + Fixed cached sector is not flushed when create and close without write. + + Apr 01, 2008 R0.06 Added f_forward(). (Tiny-FatFs) + Added string functions: fputc(), fputs(), fprintf() and fgets(). + Improved performance of f_lseek() on move to the same or following cluster. + + Apr 01, 2009, R0.07 Merged Tiny-FatFs as a buffer configuration option. + Added long file name support. + Added multiple code page support. + Added re-entrancy for multitask operation. + Added auto cluster size selection to f_mkfs(). + Added rewind option to f_readdir(). + Changed result code of critical errors. + Renamed string functions to avoid name collision. + + Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg. + Added multiple sector size support. + + Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error. + Fixed wrong cache control in f_lseek(). + Added relative path feature. + Added f_chdir(). + Added f_chdrive(). + Added proper case conversion for extended characters. + + Nov 03,'2009 R0.07e Separated out configuration options from ff.h to ffconf.h. + Added a configuration option, _LFN_UNICODE. + Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. + Fixed name matching error on the 13 char boundary. + Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. diff --git a/Projects/TemperatureDataLogger/Lib/FATFs/diskio.c b/Projects/TemperatureDataLogger/Lib/FATFs/diskio.c new file mode 100644 index 000000000..e6be68734 --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/FATFs/diskio.c @@ -0,0 +1,87 @@ +/*-----------------------------------------------------------------------*/ +/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */ +/*-----------------------------------------------------------------------*/ +/* This is a stub disk I/O module that acts as front end of the existing */ +/* disk I/O modules and attach it to FatFs module with common interface. */ +/*-----------------------------------------------------------------------*/ + +#include "diskio.h" + +/*-----------------------------------------------------------------------*/ +/* Inidialize a Drive */ + +DSTATUS disk_initialize ( + BYTE drv /* Physical drive nmuber (0..) */ +) +{ + return FR_OK; +} + + + +/*-----------------------------------------------------------------------*/ +/* Return Disk Status */ + +DSTATUS disk_status ( + BYTE drv /* Physical drive nmuber (0..) */ +) +{ + return FR_OK; +} + + + +/*-----------------------------------------------------------------------*/ +/* Read Sector(s) */ + +DRESULT disk_read ( + BYTE drv, /* Physical drive nmuber (0..) */ + BYTE *buff, /* Data buffer to store read data */ + DWORD sector, /* Sector address (LBA) */ + BYTE count /* Number of sectors to read (1..255) */ +) +{ + DataflashManager_ReadBlocks_RAM(sector, count, buff); + return RES_OK; +} + + + +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ + +#if _READONLY == 0 +DRESULT disk_write ( + BYTE drv, /* Physical drive nmuber (0..) */ + const BYTE *buff, /* Data to be written */ + DWORD sector, /* Sector address (LBA) */ + BYTE count /* Number of sectors to write (1..255) */ +) +{ + DataflashManager_WriteBlocks_RAM(sector, count, buff); + return RES_OK; +} +#endif /* _READONLY */ + + + +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ + +DRESULT disk_ioctl ( + BYTE drv, /* Physical drive nmuber (0..) */ + BYTE ctrl, /* Control code */ + void *buff /* Buffer to send/receive control data */ +) +{ + if (ctrl == CTRL_SYNC) + return RES_OK; + else + return RES_PARERR; +} + + +DWORD get_fattime (void) +{ + return (1UL << 25) | (1UL << 21) | (1UL << 16) | (1UL << 11) | (1UL << 5) | (1UL << 0); +} diff --git a/Projects/TemperatureDataLogger/Lib/FATFs/diskio.h b/Projects/TemperatureDataLogger/Lib/FATFs/diskio.h new file mode 100644 index 000000000..b03cece66 --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/FATFs/diskio.h @@ -0,0 +1,71 @@ +/*----------------------------------------------------------------------- +/ Low level disk interface modlue include file R0.07 (C)ChaN, 2009 +/-----------------------------------------------------------------------*/ + +#ifndef _DISKIO + +#define _READONLY 0 /* 1: Read-only mode */ +#define _USE_IOCTL 1 + +#include "integer.h" + +#include "../DataflashManager.h" + + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /* 0: Successful */ + RES_ERROR, /* 1: R/W Error */ + RES_WRPRT, /* 2: Write Protected */ + RES_NOTRDY, /* 3: Not Ready */ + RES_PARERR /* 4: Invalid Parameter */ +} DRESULT; + + +/*---------------------------------------*/ +/* Prototypes for disk control functions */ + +BOOL assign_drives (int argc, char *argv[]); +DSTATUS disk_initialize (BYTE); +DSTATUS disk_status (BYTE); +DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE); +#if _READONLY == 0 +DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE); +#endif +DRESULT disk_ioctl (BYTE, BYTE, void*); + + +/* Disk Status Bits (DSTATUS) */ + +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ +#define STA_PROTECT 0x04 /* Write protected */ + + +/* Command code for disk_ioctrl() */ + +/* Generic command */ +#define CTRL_SYNC 0 /* Mandatory for write functions */ +#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */ +#define GET_SECTOR_SIZE 2 /* Mandatory for multiple sector size cfg */ +#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */ +#define CTRL_POWER 4 +#define CTRL_LOCK 5 +#define CTRL_EJECT 6 +/* MMC/SDC command */ +#define MMC_GET_TYPE 10 +#define MMC_GET_CSD 11 +#define MMC_GET_CID 12 +#define MMC_GET_OCR 13 +#define MMC_GET_SDSTAT 14 +/* ATA/CF command */ +#define ATA_GET_REV 20 +#define ATA_GET_MODEL 21 +#define ATA_GET_SN 22 + + +#define _DISKIO +#endif diff --git a/Projects/TemperatureDataLogger/Lib/FATFs/diskio.lst b/Projects/TemperatureDataLogger/Lib/FATFs/diskio.lst new file mode 100644 index 000000000..baedc5ab0 --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/FATFs/diskio.lst @@ -0,0 +1,149 @@ + 1 .file "diskio.c" + 2 __SREG__ = 0x3f + 3 __SP_H__ = 0x3e + 4 __SP_L__ = 0x3d + 5 __CCP__ = 0x34 + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 15 .Ltext0: + 16 .section .text.disk_initialize,"ax",@progbits + 17 .global disk_initialize + 19 disk_initialize: + 20 .LFB52: + 21 .LSM0: + 22 .LVL0: + 23 /* prologue: function */ + 24 /* frame size = 0 */ + 25 .LSM1: + 26 0000 80E0 ldi r24,lo8(0) + 27 .LVL1: + 28 /* epilogue start */ + 29 0002 0895 ret + 30 .LFE52: + 32 .section .text.disk_status,"ax",@progbits + 33 .global disk_status + 35 disk_status: + 36 .LFB53: + 37 .LSM2: + 38 .LVL2: + 39 /* prologue: function */ + 40 /* frame size = 0 */ + 41 .LSM3: + 42 0000 80E0 ldi r24,lo8(0) + 43 .LVL3: + 44 /* epilogue start */ + 45 0002 0895 ret + 46 .LFE53: + 48 .section .text.disk_ioctl,"ax",@progbits + 49 .global disk_ioctl + 51 disk_ioctl: + 52 .LFB56: + 53 .LSM4: + 54 .LVL4: + 55 /* prologue: function */ + 56 /* frame size = 0 */ + 57 .LSM5: + 58 0000 6623 tst r22 + 59 0002 01F0 breq .L6 + 60 0004 84E0 ldi r24,lo8(4) + 61 .LVL5: + 62 0006 0895 ret + 63 .LVL6: + 64 .L6: + 65 0008 80E0 ldi r24,lo8(0) + 66 .LVL7: + 67 .LSM6: + 68 000a 0895 ret + 69 .LFE56: + 71 .section .text.get_fattime,"ax",@progbits + 72 .global get_fattime + 74 get_fattime: + 75 .LFB57: + 76 .LSM7: + 77 /* prologue: function */ + 78 /* frame size = 0 */ + 79 .LSM8: + 80 0000 61E2 ldi r22,lo8(35719201) + 81 0002 78E0 ldi r23,hi8(35719201) + 82 0004 81E2 ldi r24,hlo8(35719201) + 83 0006 92E0 ldi r25,hhi8(35719201) + 84 /* epilogue start */ + 85 0008 0895 ret + 86 .LFE57: + 88 .section .text.disk_write,"ax",@progbits + 89 .global disk_write + 91 disk_write: + 92 .LFB55: + 93 .LSM9: + 94 .LVL8: + 95 0000 0F93 push r16 + 96 .LVL9: + 97 /* prologue: function */ + 98 /* frame size = 0 */ + 99 0002 FB01 movw r30,r22 + 100 .LSM10: + 101 0004 CA01 movw r24,r20 + 102 0006 B901 movw r22,r18 + 103 .LVL10: + 104 0008 402F mov r20,r16 + 105 .LVL11: + 106 000a 50E0 ldi r21,lo8(0) + 107 000c 9F01 movw r18,r30 + 108 .LVL12: + 109 000e 0E94 0000 call DataflashManager_WriteBlocks_RAM + 110 .LVL13: + 111 .LSM11: + 112 0012 80E0 ldi r24,lo8(0) + 113 /* epilogue start */ + 114 0014 0F91 pop r16 + 115 .LVL14: + 116 0016 0895 ret + 117 .LFE55: + 119 .section .text.disk_read,"ax",@progbits + 120 .global disk_read + 122 disk_read: + 123 .LFB54: + 124 .LSM12: + 125 .LVL15: + 126 0000 0F93 push r16 + 127 .LVL16: + 128 /* prologue: function */ + 129 /* frame size = 0 */ + 130 0002 FB01 movw r30,r22 + 131 .LSM13: + 132 0004 CA01 movw r24,r20 + 133 0006 B901 movw r22,r18 + 134 .LVL17: + 135 0008 402F mov r20,r16 + 136 .LVL18: + 137 000a 50E0 ldi r21,lo8(0) + 138 000c 9F01 movw r18,r30 + 139 .LVL19: + 140 000e 0E94 0000 call DataflashManager_ReadBlocks_RAM + 141 .LVL20: + 142 .LSM14: + 143 0012 80E0 ldi r24,lo8(0) + 144 /* epilogue start */ + 145 0014 0F91 pop r16 + 146 .LVL21: + 147 0016 0895 ret + 148 .LFE54: + 214 .Letext0: +DEFINED SYMBOLS + *ABS*:00000000 diskio.c +C:\Users\Dean\AppData\Local\Temp/ccUCer1P.s:2 *ABS*:0000003f __SREG__ +C:\Users\Dean\AppData\Local\Temp/ccUCer1P.s:3 *ABS*:0000003e __SP_H__ +C:\Users\Dean\AppData\Local\Temp/ccUCer1P.s:4 *ABS*:0000003d __SP_L__ +C:\Users\Dean\AppData\Local\Temp/ccUCer1P.s:5 *ABS*:00000034 __CCP__ +C:\Users\Dean\AppData\Local\Temp/ccUCer1P.s:6 *ABS*:00000000 __tmp_reg__ +C:\Users\Dean\AppData\Local\Temp/ccUCer1P.s:7 *ABS*:00000001 __zero_reg__ +C:\Users\Dean\AppData\Local\Temp/ccUCer1P.s:19 .text.disk_initialize:00000000 disk_initialize +C:\Users\Dean\AppData\Local\Temp/ccUCer1P.s:35 .text.disk_status:00000000 disk_status +C:\Users\Dean\AppData\Local\Temp/ccUCer1P.s:51 .text.disk_ioctl:00000000 disk_ioctl +C:\Users\Dean\AppData\Local\Temp/ccUCer1P.s:74 .text.get_fattime:00000000 get_fattime +C:\Users\Dean\AppData\Local\Temp/ccUCer1P.s:91 .text.disk_write:00000000 disk_write +C:\Users\Dean\AppData\Local\Temp/ccUCer1P.s:122 .text.disk_read:00000000 disk_read + +UNDEFINED SYMBOLS +DataflashManager_WriteBlocks_RAM +DataflashManager_ReadBlocks_RAM diff --git a/Projects/TemperatureDataLogger/Lib/FATFs/ff.c b/Projects/TemperatureDataLogger/Lib/FATFs/ff.c new file mode 100644 index 000000000..80efa7b48 --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/FATFs/ff.c @@ -0,0 +1,3153 @@ +/*----------------------------------------------------------------------------/ +/ FatFs - FAT file system module R0.07e (C)ChaN, 2009 +/-----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following trems. +/ +/ Copyright (C) 2009, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-----------------------------------------------------------------------------/ +/ Feb 26,'06 R0.00 Prototype. +/ +/ Apr 29,'06 R0.01 First stable version. +/ +/ Jun 01,'06 R0.02 Added FAT12 support. +/ Removed unbuffered mode. +/ Fixed a problem on small (<32M) patition. +/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM). +/ +/ Sep 22,'06 R0.03 Added f_rename(). +/ Changed option _FS_MINIMUM to _FS_MINIMIZE. +/ Dec 11,'06 R0.03a Improved cluster scan algolithm to write files fast. +/ Fixed f_mkdir() creates incorrect directory on FAT32. +/ +/ Feb 04,'07 R0.04 Supported multiple drive system. +/ Changed some interfaces for multiple drive system. +/ Changed f_mountdrv() to f_mount(). +/ Added f_mkfs(). +/ Apr 01,'07 R0.04a Supported multiple partitions on a plysical drive. +/ Added a capability of extending file size to f_lseek(). +/ Added minimization level 3. +/ Fixed an endian sensitive code in f_mkfs(). +/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG. +/ Added FSInfo support. +/ Fixed DBCS name can result FR_INVALID_NAME. +/ Fixed short seek (<= csize) collapses the file object. +/ +/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs(). +/ Fixed f_mkfs() on FAT32 creates incorrect FSInfo. +/ Fixed f_mkdir() on FAT32 creates incorrect directory. +/ Feb 03,'08 R0.05a Added f_truncate() and f_utime(). +/ Fixed off by one error at FAT sub-type determination. +/ Fixed btr in f_read() can be mistruncated. +/ Fixed cached sector is not flushed when create and close +/ without write. +/ +/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets(). +/ Improved performance of f_lseek() on moving to the same +/ or following cluster. +/ +/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a buffer configuration option. +/ Added long file name support. +/ Added multiple code page support. +/ Added re-entrancy for multitask operation. +/ Added auto cluster size selection to f_mkfs(). +/ Added rewind option to f_readdir(). +/ Changed result code of critical errors. +/ Renamed string functions to avoid name collision. +/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg. +/ Added multiple sector size support. +/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error. +/ Fixed wrong cache control in f_lseek(). +/ Added relative path feature. +/ Added f_chdir() and f_chdrive(). +/ Added proper case conversion to extended char. +/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h. +/ Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. +/ Fixed name matching error on the 13 char boundary. +/ Added a configuration option, _LFN_UNICODE. +/ Changed f_readdir() to return the SFN with always upper +/ case on non-LFN cfg. +/---------------------------------------------------------------------------*/ + +#include "ff.h" /* FatFs configurations and declarations */ +#include "diskio.h" /* Declarations of low level disk I/O functions */ + +/*-------------------------------------------------------------------------- + + Module Private Definitions + +---------------------------------------------------------------------------*/ + +#if _FATFS != 0x007E +#error Wrong include file (ff.h). +#endif + +#if _FS_REENTRANT +#if _USE_LFN == 1 +#error Static LFN work area must not be used in re-entrant configuration. +#endif +#define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; } +#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } + +#else +#define ENTER_FF(fs) +#define LEAVE_FF(fs, res) return res + +#endif + +#define ABORT(fs, res) { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); } + +#ifndef NULL +#define NULL 0 +#endif + +/* Name status flags */ +#define NS 11 /* Offset of name status byte */ +#define NS_LOSS 0x01 /* Out of 8.3 format */ +#define NS_LFN 0x02 /* Force to create LFN entry */ +#define NS_LAST 0x04 /* Last segment */ +#define NS_BODY 0x08 /* Lower case flag (body) */ +#define NS_EXT 0x10 /* Lower case flag (ext) */ +#define NS_DOT 0x20 /* Dot entry */ + + + + +/*-------------------------------------------------------------------------- + + Private Work Area + +---------------------------------------------------------------------------*/ + +#if _DRIVES < 1 || _DRIVES > 9 +#error Number of drives must be 1-9. +#endif +static +FATFS *FatFs[_DRIVES]; /* Pointer to the file system objects (logical drives) */ + +static +WORD Fsid; /* File system mount ID */ + +#if _FS_RPATH +static +BYTE Drive; /* Current drive */ +#endif + + +#if _USE_LFN == 1 /* LFN with static LFN working buffer */ +static +WCHAR LfnBuf[_MAX_LFN + 1]; +#define NAMEBUF(sp,lp) BYTE sp[12]; WCHAR *lp = LfnBuf +#define INITBUF(dj,sp,lp) dj.fn = sp; dj.lfn = lp + +#elif _USE_LFN > 1 /* LFN with dynamic LFN working buffer */ +#define NAMEBUF(sp,lp) BYTE sp[12]; WCHAR lbuf[_MAX_LFN + 1], *lp = lbuf +#define INITBUF(dj,sp,lp) dj.fn = sp; dj.lfn = lp + +#else /* No LFN */ +#define NAMEBUF(sp,lp) BYTE sp[12] +#define INITBUF(dj,sp,lp) dj.fn = sp + +#endif + + + + +/*-------------------------------------------------------------------------- + + Module Private Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* String functions */ +/*-----------------------------------------------------------------------*/ + +/* Copy memory to memory */ +static +void mem_cpy (void* dst, const void* src, int cnt) { + char *d = (char*)dst; + const char *s = (const char *)src; + while (cnt--) *d++ = *s++; +} + +/* Fill memory */ +static +void mem_set (void* dst, int val, int cnt) { + char *d = (char*)dst; + while (cnt--) *d++ = (char)val; +} + +/* Compare memory to memory */ +static +int mem_cmp (const void* dst, const void* src, int cnt) { + const char *d = (const char *)dst, *s = (const char *)src; + int r = 0; + while (cnt-- && (r = *d++ - *s++) == 0) ; + return r; +} + +/* Check if chr is contained in the string */ +static +int chk_chr (const char* str, int chr) { + while (*str && *str != chr) str++; + return *str; +} + + + +/*-----------------------------------------------------------------------*/ +/* Request/Release grant to access the volume */ +/*-----------------------------------------------------------------------*/ +#if _FS_REENTRANT + +static +BOOL lock_fs ( + FATFS *fs /* File system object */ +) +{ + return ff_req_grant(fs->sobj); +} + + +static +void unlock_fs ( + FATFS *fs, /* File system object */ + FRESULT res /* Result code to be returned */ +) +{ + if (res != FR_NOT_ENABLED && + res != FR_INVALID_DRIVE && + res != FR_INVALID_OBJECT && + res != FR_TIMEOUT) { + ff_rel_grant(fs->sobj); + } +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Change window offset */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT move_window ( + FATFS *fs, /* File system object */ + DWORD sector /* Sector number to make apperance in the fs->win[] */ +) /* Move to zero only writes back dirty window */ +{ + DWORD wsect; + + + wsect = fs->winsect; + if (wsect != sector) { /* Changed current window */ +#if !_FS_READONLY + if (fs->wflag) { /* Write back dirty window if needed */ + if (disk_write(fs->drive, fs->win, wsect, 1) != RES_OK) + return FR_DISK_ERR; + fs->wflag = 0; + if (wsect < (fs->fatbase + fs->sects_fat)) { /* In FAT area */ + BYTE nf; + for (nf = fs->n_fats; nf > 1; nf--) { /* Refrect the change to all FAT copies */ + wsect += fs->sects_fat; + disk_write(fs->drive, fs->win, wsect, 1); + } + } + } +#endif + if (sector) { + if (disk_read(fs->drive, fs->win, sector, 1) != RES_OK) + return FR_DISK_ERR; + fs->winsect = sector; + } + } + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Clean-up cached data */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT sync ( /* FR_OK: successful, FR_DISK_ERR: failed */ + FATFS *fs /* File system object */ +) +{ + FRESULT res; + + + res = move_window(fs, 0); + if (res == FR_OK) { + /* Update FSInfo sector if needed */ + if (fs->fs_type == FS_FAT32 && fs->fsi_flag) { + fs->winsect = 0; + mem_set(fs->win, 0, 512); + ST_WORD(fs->win+BS_55AA, 0xAA55); + ST_DWORD(fs->win+FSI_LeadSig, 0x41615252); + ST_DWORD(fs->win+FSI_StrucSig, 0x61417272); + ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust); + ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust); + disk_write(fs->drive, fs->win, fs->fsi_sector, 1); + fs->fsi_flag = 0; + } + /* Make sure that no pending write process in the physical drive */ + if (disk_ioctl(fs->drive, CTRL_SYNC, (void*)NULL) != RES_OK) + res = FR_DISK_ERR; + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Read value of a FAT entry */ +/*-----------------------------------------------------------------------*/ + + +DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Interal error, Else:Cluster status */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to get the link information */ +) +{ + UINT wc, bc; + DWORD fsect; + + + if (clst < 2 || clst >= fs->max_clust) /* Range check */ + return 1; + + fsect = fs->fatbase; + switch (fs->fs_type) { + case FS_FAT12 : + bc = clst; bc += bc / 2; + if (move_window(fs, fsect + (bc / SS(fs)))) break; + wc = fs->win[bc & (SS(fs) - 1)]; bc++; + if (move_window(fs, fsect + (bc / SS(fs)))) break; + wc |= (WORD)fs->win[bc & (SS(fs) - 1)] << 8; + return (clst & 1) ? (wc >> 4) : (wc & 0xFFF); + + case FS_FAT16 : + if (move_window(fs, fsect + (clst / (SS(fs) / 2)))) break; + return LD_WORD(&fs->win[((WORD)clst * 2) & (SS(fs) - 1)]); + + case FS_FAT32 : + if (move_window(fs, fsect + (clst / (SS(fs) / 4)))) break; + return LD_DWORD(&fs->win[((WORD)clst * 4) & (SS(fs) - 1)]) & 0x0FFFFFFF; + } + + return 0xFFFFFFFF; /* An error occured at the disk I/O layer */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Change value of a FAT entry */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY + +FRESULT put_fat ( + FATFS *fs, /* File system object */ + DWORD clst, /* Cluster# to be changed in range of 2 to fs->max_clust - 1 */ + DWORD val /* New value to mark the cluster */ +) +{ + UINT bc; + BYTE *p; + DWORD fsect; + FRESULT res; + + + if (clst < 2 || clst >= fs->max_clust) { /* Range check */ + res = FR_INT_ERR; + + } else { + fsect = fs->fatbase; + switch (fs->fs_type) { + case FS_FAT12 : + bc = clst; bc += bc / 2; + res = move_window(fs, fsect + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc & (SS(fs) - 1)]; + *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; + bc++; + fs->wflag = 1; + res = move_window(fs, fsect + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc & (SS(fs) - 1)]; + *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); + break; + + case FS_FAT16 : + res = move_window(fs, fsect + (clst / (SS(fs) / 2))); + if (res != FR_OK) break; + ST_WORD(&fs->win[((WORD)clst * 2) & (SS(fs) - 1)], (WORD)val); + break; + + case FS_FAT32 : + res = move_window(fs, fsect + (clst / (SS(fs) / 4))); + if (res != FR_OK) break; + ST_DWORD(&fs->win[((WORD)clst * 4) & (SS(fs) - 1)], val); + break; + + default : + res = FR_INT_ERR; + } + fs->wflag = 1; + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Remove a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT remove_chain ( + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to remove a chain from */ +) +{ + FRESULT res; + DWORD nxt; + + + if (clst < 2 || clst >= fs->max_clust) { /* Check the range of cluster# */ + res = FR_INT_ERR; + + } else { + res = FR_OK; + while (clst < fs->max_clust) { /* Not a last link? */ + nxt = get_fat(fs, clst); /* Get cluster status */ + if (nxt == 0) break; /* Empty cluster? */ + if (nxt == 1) { res = FR_INT_ERR; break; } /* Internal error? */ + if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } /* Disk error? */ + res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */ + if (res != FR_OK) break; + if (fs->free_clust != 0xFFFFFFFF) { /* Update FSInfo */ + fs->free_clust++; + fs->fsi_flag = 1; + } + clst = nxt; /* Next cluster */ + } + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Stretch or Create a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to stretch. 0 means create a new chain. */ +) +{ + DWORD cs, ncl, scl, mcl; + + + mcl = fs->max_clust; + if (clst == 0) { /* Create new chain */ + scl = fs->last_clust; /* Get suggested start point */ + if (scl == 0 || scl >= mcl) scl = 1; + } + else { /* Stretch existing chain */ + cs = get_fat(fs, clst); /* Check the cluster status */ + if (cs < 2) return 1; /* It is an invalid cluster */ + if (cs < mcl) return cs; /* It is already followed by next cluster */ + scl = clst; + } + + ncl = scl; /* Start cluster */ + for (;;) { + ncl++; /* Next cluster */ + if (ncl >= mcl) { /* Wrap around */ + ncl = 2; + if (ncl > scl) return 0; /* No free custer */ + } + cs = get_fat(fs, ncl); /* Get the cluster status */ + if (cs == 0) break; /* Found a free cluster */ + if (cs == 0xFFFFFFFF || cs == 1)/* An error occured */ + return cs; + if (ncl == scl) return 0; /* No free custer */ + } + + if (put_fat(fs, ncl, 0x0FFFFFFF)) /* Mark the new cluster "in use" */ + return 0xFFFFFFFF; + if (clst != 0) { /* Link it to the previous one if needed */ + if (put_fat(fs, clst, ncl)) + return 0xFFFFFFFF; + } + + fs->last_clust = ncl; /* Update FSINFO */ + if (fs->free_clust != 0xFFFFFFFF) { + fs->free_clust--; + fs->fsi_flag = 1; + } + + return ncl; /* Return new cluster number */ +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Get sector# from cluster# */ +/*-----------------------------------------------------------------------*/ + + +DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to be converted */ +) +{ + clst -= 2; + if (clst >= (fs->max_clust - 2)) return 0; /* Invalid cluster# */ + return clst * fs->csize + fs->database; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Seek directory index */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_seek ( + DIR *dj, /* Pointer to directory object */ + WORD idx /* Directory index number */ +) +{ + DWORD clst; + WORD ic; + + + dj->index = idx; + clst = dj->sclust; + if (clst == 1 || clst >= dj->fs->max_clust) /* Check start cluster range */ + return FR_INT_ERR; + if (!clst && dj->fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */ + clst = dj->fs->dirbase; + + if (clst == 0) { /* Static table */ + dj->clust = clst; + if (idx >= dj->fs->n_rootdir) /* Index is out of range */ + return FR_INT_ERR; + dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / 32); /* Sector# */ + } + else { /* Dynamic table */ + ic = SS(dj->fs) / 32 * dj->fs->csize; /* Entries per cluster */ + while (idx >= ic) { /* Follow cluster chain */ + clst = get_fat(dj->fs, clst); /* Get next cluster */ + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ + if (clst < 2 || clst >= dj->fs->max_clust) /* Reached to end of table or int error */ + return FR_INT_ERR; + idx -= ic; + } + dj->clust = clst; + dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / 32); /* Sector# */ + } + + dj->dir = dj->fs->win + (idx % (SS(dj->fs) / 32)) * 32; /* Ptr to the entry in the sector */ + + return FR_OK; /* Seek succeeded */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Move directory index next */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not streach */ + DIR *dj, /* Pointer to directory object */ + BOOL streach /* FALSE: Do not streach table, TRUE: Streach table if needed */ +) +{ + DWORD clst; + WORD i; + + + i = dj->index + 1; + if (!i || !dj->sect) /* Report EOT when index has reached 65535 */ + return FR_NO_FILE; + + if (!(i % (SS(dj->fs) / 32))) { /* Sector changed? */ + dj->sect++; /* Next sector */ + + if (dj->clust == 0) { /* Static table */ + if (i >= dj->fs->n_rootdir) /* Report EOT when end of table */ + return FR_NO_FILE; + } + else { /* Dynamic table */ + if (((i / (SS(dj->fs) / 32)) & (dj->fs->csize - 1)) == 0) { /* Cluster changed? */ + clst = get_fat(dj->fs, dj->clust); /* Get next cluster */ + if (clst <= 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + if (clst >= dj->fs->max_clust) { /* When it reached end of dynamic table */ +#if !_FS_READONLY + BYTE c; + if (!streach) return FR_NO_FILE; /* When do not streach, report EOT */ + clst = create_chain(dj->fs, dj->clust); /* Streach cluster chain */ + if (clst == 0) return FR_DENIED; /* No free cluster */ + if (clst == 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + /* Clean-up streached table */ + if (move_window(dj->fs, 0)) return FR_DISK_ERR; /* Flush active window */ + mem_set(dj->fs->win, 0, SS(dj->fs)); /* Clear window buffer */ + dj->fs->winsect = clust2sect(dj->fs, clst); /* Cluster start sector */ + for (c = 0; c < dj->fs->csize; c++) { /* Fill the new cluster with 0 */ + dj->fs->wflag = 1; + if (move_window(dj->fs, 0)) return FR_DISK_ERR; + dj->fs->winsect++; + } + dj->fs->winsect -= c; /* Rewind window address */ +#else + return FR_NO_FILE; /* Report EOT */ +#endif + } + dj->clust = clst; /* Initialize data for new cluster */ + dj->sect = clust2sect(dj->fs, clst); + } + } + } + + dj->index = i; + dj->dir = dj->fs->win + (i % (SS(dj->fs) / 32)) * 32; + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* Offset of LFN chars in the directory entry */ + + +static +BOOL cmp_lfn ( /* TRUE:Matched, FALSE:Not matched */ + WCHAR *lfnbuf, /* Pointer to the LFN to be compared */ + BYTE *dir /* Pointer to the directory entry containing a part of LFN */ +) +{ + int i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0xBF) - 1) * 13; /* Get offset in the LFN buffer */ + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + wc = ff_wtoupper(uc); /* Convert it to upper case */ + if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */ + return FALSE; /* Not matched */ + } else { + if (uc != 0xFFFF) return FALSE; /* Check filler */ + } + } while (++s < 13); /* Repeat until all chars in the entry are checked */ + + if ((dir[LDIR_Ord] & 0x40) && wc && lfnbuf[i]) /* Last segment matched but different length */ + return FALSE; + + return TRUE; /* The part of LFN matched */ +} + + + +static +BOOL pick_lfn ( /* TRUE:Succeeded, FALSE:Buffer overflow */ + WCHAR *lfnbuf, /* Pointer to the Unicode-LFN buffer */ + BYTE *dir /* Pointer to the directory entry */ +) +{ + int i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */ + + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + if (i >= _MAX_LFN) return FALSE; /* Buffer overflow? */ + lfnbuf[i++] = wc = uc; /* Store it */ + } else { + if (uc != 0xFFFF) return FALSE; /* Check filler */ + } + } while (++s < 13); /* Read all character in the entry */ + + if (dir[LDIR_Ord] & 0x40) { /* Put terminator if it is the last LFN part */ + if (i >= _MAX_LFN) return FALSE; /* Buffer overflow? */ + lfnbuf[i] = 0; + } + + return TRUE; +} + + +#if !_FS_READONLY +static +void fit_lfn ( + const WCHAR *lfnbuf, /* Pointer to the LFN buffer */ + BYTE *dir, /* Pointer to the directory entry */ + BYTE ord, /* LFN order (1-20) */ + BYTE sum /* SFN sum */ +) +{ + int i, s; + WCHAR wc; + + + dir[LDIR_Chksum] = sum; /* Set check sum */ + dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */ + dir[LDIR_Type] = 0; + ST_WORD(dir+LDIR_FstClusLO, 0); + + i = (ord - 1) * 13; /* Get offset in the LFN buffer */ + s = wc = 0; + do { + if (wc != 0xFFFF) wc = lfnbuf[i++]; /* Get an effective char */ + ST_WORD(dir+LfnOfs[s], wc); /* Put it */ + if (!wc) wc = 0xFFFF; /* Padding chars following last char */ + } while (++s < 13); + if (wc == 0xFFFF || !lfnbuf[i]) ord |= 0x40; /* Bottom LFN part is the start of LFN sequence */ + dir[LDIR_Ord] = ord; /* Set the LFN order */ +} + +#endif +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Create numbered name */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +void gen_numname ( + BYTE *dst, /* Pointer to genartated SFN */ + const BYTE *src, /* Pointer to source SFN to be modified */ + const WCHAR *lfn, /* Pointer to LFN */ + WORD num /* Sequense number */ +) +{ + char ns[8]; + int i, j; + + + mem_cpy(dst, src, 11); + + if (num > 5) { /* On many collisions, generate a hash number instead of sequencial number */ + do num = (num >> 1) + (num << 15) + (WORD)*lfn++; while (*lfn); + } + + /* itoa */ + i = 7; + do { + ns[i--] = (num % 10) + '0'; + num /= 10; + } while (num); + ns[i] = '~'; + + /* Append the number */ + for (j = 0; j < i && dst[j] != ' '; j++) { + if (IsDBCS1(dst[j])) { + if (j == i - 1) break; + j++; + } + } + do { + dst[j++] = (i < 8) ? ns[i++] : ' '; + } while (j < 8); +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Calculate sum of an SFN */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +BYTE sum_sfn ( + const BYTE *dir /* Ptr to directory entry */ +) +{ + BYTE sum = 0; + int n = 11; + + do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n); + return sum; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Find an object in the directory */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_find ( + DIR *dj /* Pointer to the directory object linked to the file name */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord, sum; +#endif + + res = dir_seek(dj, 0); /* Rewind directory object */ + if (res != FR_OK) return res; + +#if _USE_LFN + ord = sum = 0xFF; +#endif + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == 0xE5 || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (dj->lfn) { + if (c & 0x40) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= 0xBF; ord = c; /* LFN start order */ + dj->lfn_idx = dj->index; + } + /* Check validity of the LFN entry and compare it with given name */ + ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } + } else { /* An SFN entry is found */ + if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */ + ord = 0xFF; dj->lfn_idx = 0xFFFF; /* Reset LFN sequence */ + if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break; /* SFN matched? */ + } + } +#else /* Non LFN configuration */ + if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, FALSE); /* Next entry */ + } while (res == FR_OK); + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 +static +FRESULT dir_read ( + DIR *dj /* Pointer to the directory object that pointing the entry to be read */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord = 0xFF, sum = 0xFF; +#endif + + res = FR_NO_FILE; + while (dj->sect) { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == 0xE5 || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (c & 0x40) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= 0xBF; ord = c; + dj->lfn_idx = dj->index; + } + /* Check LFN validity and capture it */ + ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } else { /* An SFN entry is found */ + if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN? */ + dj->lfn_idx = 0xFFFF; /* It has no LFN. */ + break; + } + } +#else /* Non LFN configuration */ + if (c != 0xE5 && (_FS_RPATH || c != '.') && !(dir[DIR_Attr] & AM_VOL)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, FALSE); /* Next entry */ + if (res != FR_OK) break; + } + + if (res != FR_OK) dj->sect = 0; + + return res; +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Register an object to the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */ + DIR *dj /* Target directory with object name to be created */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN /* LFN configuration */ + WORD n, ne, is; + BYTE sn[12], *fn, sum; + WCHAR *lfn; + + + fn = dj->fn; lfn = dj->lfn; + mem_cpy(sn, fn, 12); + + if (_FS_RPATH && (sn[NS] & NS_DOT)) return FR_INVALID_NAME; /* Cannot create dot entry */ + + if (sn[NS] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ + fn[NS] = 0; dj->lfn = NULL; /* Find only SFN */ + for (n = 1; n < 100; n++) { + gen_numname(fn, sn, lfn, n); /* Generate a numbered name */ + res = dir_find(dj); /* Check if the name collides with existing SFN */ + if (res != FR_OK) break; + } + if (n == 100) return FR_DENIED; /* Abort if too many collisions */ + if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */ + fn[NS] = sn[NS]; dj->lfn = lfn; + } + + if (sn[NS] & NS_LFN) { /* When LFN is to be created, reserve reserve an SFN + LFN entries. */ + for (ne = 0; lfn[ne]; ne++) ; + ne = (ne + 25) / 13; + } else { /* Otherwise reserve only an SFN entry. */ + ne = 1; + } + + /* Reserve contiguous entries */ + res = dir_seek(dj, 0); + if (res != FR_OK) return res; + n = is = 0; + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + c = *dj->dir; /* Check the entry status */ + if (c == 0xE5 || c == 0) { /* Is it a blank entry? */ + if (n == 0) is = dj->index; /* First index of the contigulus entry */ + if (++n == ne) break; /* A contiguous entry that requiered count is found */ + } else { + n = 0; /* Not a blank entry. Restart to search */ + } + res = dir_next(dj, TRUE); /* Next entry with table streach */ + } while (res == FR_OK); + + if (res == FR_OK && ne > 1) { /* Initialize LFN entry if needed */ + res = dir_seek(dj, is); + if (res == FR_OK) { + sum = sum_sfn(dj->fn); /* Sum of the SFN tied to the LFN */ + ne--; + do { /* Store LFN entries in bottom first */ + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum); + dj->fs->wflag = 1; + res = dir_next(dj, FALSE); /* Next entry */ + } while (res == FR_OK && --ne); + } + } + +#else /* Non LFN configuration */ + res = dir_seek(dj, 0); + if (res == FR_OK) { + do { /* Find a blank entry for the SFN */ + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + c = *dj->dir; + if (c == 0xE5 || c == 0) break; /* Is it a blank entry? */ + res = dir_next(dj, TRUE); /* Next entry with table streach */ + } while (res == FR_OK); + } +#endif + + if (res == FR_OK) { /* Initialize the SFN entry */ + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + dir = dj->dir; + mem_set(dir, 0, 32); /* Clean the entry */ + mem_cpy(dir, dj->fn, 11); /* Put SFN */ + dir[DIR_NTres] = *(dj->fn+NS) & (NS_BODY | NS_EXT); /* Put NT flag */ + dj->fs->wflag = 1; + } + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Remove an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY && !_FS_MINIMIZE +static +FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */ + DIR *dj /* Directory object pointing the entry to be removed */ +) +{ + FRESULT res; +#if _USE_LFN /* LFN configuration */ + WORD i; + + i = dj->index; /* SFN index */ + res = dir_seek(dj, (WORD)((dj->lfn_idx == 0xFFFF) ? i : dj->lfn_idx)); /* Goto the SFN or top of the LFN entries */ + if (res == FR_OK) { + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + *dj->dir = 0xE5; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + if (dj->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */ + res = dir_next(dj, FALSE); /* Next entry */ + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR; + } + +#else /* Non LFN configuration */ + res = dir_seek(dj, dj->index); + if (res == FR_OK) { + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + *dj->dir = 0xE5; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + } + } +#endif + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Pick a segment and create the object name in directory form */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT create_name ( + DIR *dj, /* Pointer to the directory object */ + const XCHAR **path /* Pointer to pointer to the segment in the path string */ +) +{ +#ifdef _EXCVT + static const BYTE cvt[] = _EXCVT; +#endif + +#if _USE_LFN /* LFN configuration */ + BYTE b, cf; + WCHAR w, *lfn; + int i, ni, si, di; + const XCHAR *p; + + /* Create LFN in Unicode */ + si = di = 0; + p = *path; + lfn = dj->lfn; + for (;;) { + w = p[si++]; /* Get a character */ + if (w < ' ' || w == '/' || w == '\\') break; /* Break on end of segment */ + if (di >= _MAX_LFN) /* Reject too long name */ + return FR_INVALID_NAME; +#if !_LFN_UNICODE + w &= 0xFF; + if (IsDBCS1(w)) { /* If it is a DBC 1st byte */ + b = p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(b)) /* Reject invalid code for DBC */ + return FR_INVALID_NAME; + w = (w << 8) + b; + } + w = ff_convert(w, 1); /* Convert OEM to Unicode */ + if (!w) return FR_INVALID_NAME; /* Reject invalid code */ +#endif + if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal chars for LFN */ + return FR_INVALID_NAME; + lfn[di++] = w; /* Store the Unicode char */ + } + *path = &p[si]; /* Rerurn pointer to the next segment */ + cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ +#if _FS_RPATH + if ((di == 1 && lfn[di - 1] == '.') || /* Is this a dot entry? */ + (di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) { + lfn[di] = 0; + for (i = 0; i < 11; i++) + dj->fn[i] = (i < di) ? '.' : ' '; + dj->fn[i] = cf | NS_DOT; /* This is a dot entry */ + return FR_OK; + } +#endif + while (di) { /* Strip trailing spaces and dots */ + w = lfn[di - 1]; + if (w != ' ' && w != '.') break; + di--; + } + if (!di) return FR_INVALID_NAME; /* Reject null string */ + + lfn[di] = 0; /* LFN is created */ + + /* Create SFN in directory form */ + mem_set(dj->fn, ' ', 11); + for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ; /* Strip leading spaces and dots */ + if (si) cf |= NS_LOSS | NS_LFN; + while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */ + + b = i = 0; ni = 8; + for (;;) { + w = lfn[si++]; /* Get an LFN char */ + if (!w) break; /* Break on enf of the LFN */ + if (w == ' ' || (w == '.' && si != di)) { /* Remove spaces and dots */ + cf |= NS_LOSS | NS_LFN; continue; + } + + if (i >= ni || si == di) { /* Extension or end of SFN */ + if (ni == 11) { /* Long extension */ + cf |= NS_LOSS | NS_LFN; break; + } + if (si != di) cf |= NS_LOSS | NS_LFN; /* Out of 8.3 format */ + if (si > di) break; /* No extension */ + si = di; i = 8; ni = 11; /* Enter extension section */ + b <<= 2; continue; + } + + if (w >= 0x80) { /* Non ASCII char */ +#ifdef _EXCVT + w = ff_convert(w, 0); /* Unicode -> OEM code */ + if (w) w = cvt[w - 0x80]; /* Convert extended char to upper (SBCS) */ +#else + w = ff_convert(ff_wtoupper(w), 0); /* Upper converted Unicode -> OEM code */ +#endif + cf |= NS_LFN; /* Force create LFN entry */ + } + + if (_DF1S && w >= 0x100) { /* Double byte char */ + if (i >= ni - 1) { + cf |= NS_LOSS | NS_LFN; i = ni; continue; + } + dj->fn[i++] = (BYTE)(w >> 8); + } else { /* Single byte char */ + if (!w || chk_chr("+,;[=]", w)) { /* Replace illegal chars for SFN */ + w = '_'; cf |= NS_LOSS | NS_LFN; /* Lossy conversion */ + } else { + if (IsUpper(w)) { /* ASCII large capital */ + b |= 2; + } else { + if (IsLower(w)) { /* ASCII small capital */ + b |= 1; w -= 0x20; + } + } + } + } + dj->fn[i++] = (BYTE)w; + } + + if (dj->fn[0] == 0xE5) dj->fn[0] = 0x05; /* If the first char collides with deleted mark, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */ + cf |= NS_LFN; + if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended char, NT flags are created */ + if ((b & 0x03) == 0x01) cf |= NS_EXT; /* NT flag (Extension has only small capital) */ + if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */ + } + + dj->fn[NS] = cf; /* SFN is created */ + + return FR_OK; + + +#else /* Non-LFN configuration */ + BYTE b, c, d, *sfn; + int ni, si, i; + const char *p; + + /* Create file name in directory form */ + sfn = dj->fn; + mem_set(sfn, ' ', 11); + si = i = b = 0; ni = 8; + p = *path; +#if _FS_RPATH + if (p[si] == '.') { /* Is this a dot entry? */ + for (;;) { + c = p[si++]; + if (c != '.' || si >= 3) break; + sfn[i++] = c; + } + if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME; + *path = &p[si]; /* Rerurn pointer to the next segment */ + sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */ + return FR_OK; + } +#endif + for (;;) { + c = p[si++]; + if (c <= ' ' || c == '/' || c == '\\') break; /* Break on end of segment */ + if (c == '.' || i >= ni) { + if (ni != 8 || c != '.') return FR_INVALID_NAME; + i = 8; ni = 11; + b <<= 2; continue; + } + if (c >= 0x80) { /* Extended char */ +#ifdef _EXCVT + c = cvt[c - 0x80]; /* Convert extend char (SBCS) */ +#else + b |= 3; /* Eliminate NT flag if ext char is exist */ +#if !_DF1S /* ASCII only cfg */ + return FR_INVALID_NAME; +#endif +#endif + } + if (IsDBCS1(c)) { /* DBC 1st byte? */ + d = p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(d) || i >= ni - 1) /* Reject invalid DBC */ + return FR_INVALID_NAME; + sfn[i++] = c; + sfn[i++] = d; + } else { /* Single byte code */ + if (chk_chr(" \"*+,[=]|\x7F", c)) /* Reject illegal chrs for SFN */ + return FR_INVALID_NAME; + if (IsUpper(c)) { /* ASCII large capital? */ + b |= 2; + } else { + if (IsLower(c)) { /* ASCII small capital? */ + b |= 1; c -= 0x20; + } + } + sfn[i++] = c; + } + } + *path = &p[si]; /* Rerurn pointer to the next segment */ + c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ + + if (!i) return FR_INVALID_NAME; /* Reject null string */ + if (sfn[0] == 0xE5) sfn[0] = 0x05; /* When first char collides with 0xE5, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Extension has only small capital) */ + if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Filename has only small capital) */ + + sfn[NS] = c; /* Store NT flag, File name is created */ + + return FR_OK; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Get file information from directory entry */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 +static +void get_fileinfo ( /* No return code */ + DIR *dj, /* Pointer to the directory object */ + FILINFO *fno /* Pointer to the file information to be filled */ +) +{ + int i; + BYTE c, nt, *dir; + char *p; + + + p = fno->fname; + if (dj->sect) { + dir = dj->dir; + nt = dir[DIR_NTres]; /* NT flag */ + for (i = 0; i < 8; i++) { /* Copy name body */ + c = dir[i]; + if (c == ' ') break; + if (c == 0x05) c = 0xE5; + if (_USE_LFN && (nt & NS_BODY) && IsUpper(c)) c += 0x20; + *p++ = c; + } + if (dir[8] != ' ') { /* Copy name extension */ + *p++ = '.'; + for (i = 8; i < 11; i++) { + c = dir[i]; + if (c == ' ') break; + if (_USE_LFN && (nt & NS_EXT) && IsUpper(c)) c += 0x20; + *p++ = c; + } + } + fno->fattrib = dir[DIR_Attr]; /* Attribute */ + fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */ + fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */ + fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */ + } + *p = 0; + +#if _USE_LFN + if (fno->lfname) { + XCHAR *tp = fno->lfname; + WCHAR w, *lfn; + + i = 0; + if (dj->sect && dj->lfn_idx != 0xFFFF) {/* Get LFN if available */ + lfn = dj->lfn; + while ((w = *lfn++) != 0) { /* Get an LFN char */ +#if !_LFN_UNICODE + w = ff_convert(w, 0); /* Unicode -> OEM conversion */ + if (!w) { i = 0; break; } /* Could not convert, no LFN */ + if (_DF1S && w >= 0x100) /* Put 1st byte if it is a DBC */ + tp[i++] = (XCHAR)(w >> 8); +#endif + if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overrun, no LFN */ + tp[i++] = (XCHAR)w; + } + } + tp[i] = 0; /* Terminator */ + } +#endif +} +#endif /* _FS_MINIMIZE <= 1 */ + + + + +/*-----------------------------------------------------------------------*/ +/* Follow a file path */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ + DIR *dj, /* Directory object to return last directory and found object */ + const XCHAR *path /* Full-path string to find a file or directory */ +) +{ + FRESULT res; + BYTE *dir, last; + + + while (!_USE_LFN && *path == ' ') path++; /* Skip leading spaces */ +#if _FS_RPATH + if (*path == '/' || *path == '\\') { /* There is a heading separator */ + path++; dj->sclust = 0; /* Strip it and start from the root dir */ + } else { /* No heading saparator */ + dj->sclust = dj->fs->cdir; /* Start from the current dir */ + } +#else + if (*path == '/' || *path == '\\') /* Strip heading separator if exist */ + path++; + dj->sclust = 0; /* Start from the root dir */ +#endif + + if ((UINT)*path < ' ') { /* Null path means the start directory itself */ + res = dir_seek(dj, 0); + dj->dir = NULL; + + } else { /* Follow path */ + for (;;) { + res = create_name(dj, &path); /* Get a segment */ + if (res != FR_OK) break; + res = dir_find(dj); /* Find it */ + last = *(dj->fn+NS) & NS_LAST; + if (res != FR_OK) { /* Could not find the object */ + if (res == FR_NO_FILE && !last) + res = FR_NO_PATH; + break; + } + if (last) break; /* Last segment match. Function completed. */ + dir = dj->dir; /* There is next segment. Follow the sub directory */ + if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */ + res = FR_NO_PATH; break; + } + dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + } + } + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Load boot record and check if it is an FAT boot record */ +/*-----------------------------------------------------------------------*/ + +static +BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */ + FATFS *fs, /* File system object */ + DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */ +) +{ + if (disk_read(fs->drive, fs->win, sect, 1) != RES_OK) /* Load boot record */ + return 3; + if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always placed at offset 510 even if the sector size is >512) */ + return 2; + + if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */ + return 0; + if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146) + return 0; + + return 1; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Make sure that the file system is valid */ +/*-----------------------------------------------------------------------*/ + + +FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occured */ + const XCHAR **path, /* Pointer to pointer to the path name (drive number) */ + FATFS **rfs, /* Pointer to pointer to the found file system object */ + BYTE chk_wp /* !=0: Check media write protection for write access */ +) +{ + BYTE fmt, *tbl; + UINT vol; + DSTATUS stat; + DWORD bsect, fsize, tsect, mclst; + const XCHAR *p = *path; + FATFS *fs; + + /* Get logical drive number from the path name */ + vol = p[0] - '0'; /* Is there a drive number? */ + if (vol <= 9 && p[1] == ':') { /* Found a drive number, get and strip it */ + p += 2; *path = p; /* Return pointer to the path name */ + } else { /* No drive number is given */ +#if _FS_RPATH + vol = Drive; /* Use current drive */ +#else + vol = 0; /* Use drive 0 */ +#endif + } + + /* Check if the logical drive is valid or not */ + if (vol >= _DRIVES) /* Is the drive number valid? */ + return FR_INVALID_DRIVE; + *rfs = fs = FatFs[vol]; /* Returen pointer to the corresponding file system object */ + if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */ + + ENTER_FF(fs); /* Lock file system */ + + if (fs->fs_type) { /* If the logical drive has been mounted */ + stat = disk_status(fs->drive); + if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized (has not been changed), */ +#if !_FS_READONLY + if (chk_wp && (stat & STA_PROTECT)) /* Check write protection if needed */ + return FR_WRITE_PROTECTED; +#endif + return FR_OK; /* The file system object is valid */ + } + } + + /* The logical drive must be mounted. Following code attempts to mount the volume */ + + fs->fs_type = 0; /* Clear the file system object */ + fs->drive = (BYTE)LD2PD(vol); /* Bind the logical drive and a physical drive */ + stat = disk_initialize(fs->drive); /* Initialize low level disk I/O layer */ + if (stat & STA_NOINIT) /* Check if the drive is ready */ + return FR_NOT_READY; +#if _MAX_SS != 512 /* Get disk sector size if needed */ + if (disk_ioctl(fs->drive, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS) + return FR_NO_FILESYSTEM; +#endif +#if !_FS_READONLY + if (chk_wp && (stat & STA_PROTECT)) /* Check disk write protection if needed */ + return FR_WRITE_PROTECTED; +#endif + /* Search FAT partition on the drive */ + fmt = check_fs(fs, bsect = 0); /* Check sector 0 as an SFD format */ + if (fmt == 1) { /* Not an FAT boot record, it may be patitioned */ + /* Check a partition listed in top of the partition table */ + tbl = &fs->win[MBR_Table + LD2PT(vol) * 16]; /* Partition table */ + if (tbl[4]) { /* Is the partition existing? */ + bsect = LD_DWORD(&tbl[8]); /* Partition offset in LBA */ + fmt = check_fs(fs, bsect); /* Check the partition */ + } + } + if (fmt == 3) return FR_DISK_ERR; + if (fmt || LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* No valid FAT patition is found */ + return FR_NO_FILESYSTEM; + + /* Initialize the file system object */ + fsize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */ + if (!fsize) fsize = LD_DWORD(fs->win+BPB_FATSz32); + fs->sects_fat = fsize; + fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FAT copies */ + fsize *= fs->n_fats; /* (Number of sectors in FAT area) */ + fs->fatbase = bsect + LD_WORD(fs->win+BPB_RsvdSecCnt); /* FAT start sector (lba) */ + fs->csize = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */ + fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Nmuber of root directory entries */ + tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */ + if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32); + fs->max_clust = mclst = (tsect /* Last cluster# + 1 (Number of clusters + 2) */ + - LD_WORD(fs->win+BPB_RsvdSecCnt) - fsize - fs->n_rootdir / (SS(fs)/32) + ) / fs->csize + 2; + + fmt = FS_FAT12; /* Determine the FAT sub type */ + if (mclst >= 0xFF7) fmt = FS_FAT16; /* Number of clusters >= 0xFF5 */ + if (mclst >= 0xFFF7) fmt = FS_FAT32; /* Number of clusters >= 0xFFF5 */ + + if (fmt == FS_FAT32) + fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */ + else + fs->dirbase = fs->fatbase + fsize; /* Root directory start sector (lba) */ + fs->database = fs->fatbase + fsize + fs->n_rootdir / (SS(fs)/32); /* Data start sector (lba) */ + +#if !_FS_READONLY + /* Initialize allocation information */ + fs->free_clust = 0xFFFFFFFF; + fs->wflag = 0; + /* Get fsinfo if needed */ + if (fmt == FS_FAT32) { + fs->fsi_flag = 0; + fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo); + if (disk_read(fs->drive, fs->win, fs->fsi_sector, 1) == RES_OK && + LD_WORD(fs->win+BS_55AA) == 0xAA55 && + LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 && + LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) { + fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free); + fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count); + } + } +#endif + fs->fs_type = fmt; /* FAT sub-type */ + fs->winsect = 0; /* Invalidate sector cache */ +#if _FS_RPATH + fs->cdir = 0; /* Current directory (root dir) */ +#endif + fs->id = ++Fsid; /* File system mount ID */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Check if the file/dir object is valid or not */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */ + FATFS *fs, /* Pointer to the file system object */ + WORD id /* Member id of the target object to be checked */ +) +{ + if (!fs || !fs->fs_type || fs->id != id) + return FR_INVALID_OBJECT; + + ENTER_FF(fs); /* Lock file system */ + + if (disk_status(fs->drive) & STA_NOINIT) + return FR_NOT_READY; + + return FR_OK; +} + + + + +/*-------------------------------------------------------------------------- + + Public Functions + +--------------------------------------------------------------------------*/ + + + +/*-----------------------------------------------------------------------*/ +/* Mount/Unmount a Locical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mount ( + BYTE vol, /* Logical drive number to be mounted/unmounted */ + FATFS *fs /* Pointer to new file system object (NULL for unmount)*/ +) +{ + FATFS *rfs; + + + if (vol >= _DRIVES) /* Check if the drive number is valid */ + return FR_INVALID_DRIVE; + rfs = FatFs[vol]; /* Get current fs object */ + + if (rfs) { +#if _FS_REENTRANT /* Discard sync object of the current volume */ + if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR; +#endif + rfs->fs_type = 0; /* Clear old fs object */ + } + + if (fs) { + fs->fs_type = 0; /* Clear new fs object */ +#if _FS_REENTRANT /* Create sync object for the new volume */ + if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR; +#endif + } + FatFs[vol] = fs; /* Register new fs object */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Open or Create a File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_open ( + FIL *fp, /* Pointer to the blank file object */ + const XCHAR *path, /* Pointer to the file name */ + BYTE mode /* Access mode and file open mode flags */ +) +{ + FRESULT res; + DIR dj; + NAMEBUF(sfn, lfn); + BYTE *dir; + + + fp->fs = NULL; /* Clear file object */ +#if !_FS_READONLY + mode &= (FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW); + res = chk_mounted(&path, &dj.fs, (BYTE)(mode & (FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW))); +#else + mode &= FA_READ; + res = chk_mounted(&path, &dj.fs, 0); +#endif + if (res != FR_OK) LEAVE_FF(dj.fs, res); + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + +#if !_FS_READONLY + /* Create or Open a file */ + if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { + DWORD ps, cl; + + if (res != FR_OK) { /* No file, create new */ + if (res == FR_NO_FILE) /* There is no file to open, create a new entry */ + res = dir_register(&dj); + if (res != FR_OK) LEAVE_FF(dj.fs, res); + mode |= FA_CREATE_ALWAYS; + dir = dj.dir; /* Created entry (SFN entry) */ + } + else { /* Any object is already existing */ + if (mode & FA_CREATE_NEW) /* Cannot create new */ + LEAVE_FF(dj.fs, FR_EXIST); + dir = dj.dir; + if (!dir || (dir[DIR_Attr] & (AM_RDO | AM_DIR))) /* Cannot overwrite it (R/O or DIR) */ + LEAVE_FF(dj.fs, FR_DENIED); + if (mode & FA_CREATE_ALWAYS) { /* Resize it to zero on over write mode */ + cl = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); /* Get start cluster */ + ST_WORD(dir+DIR_FstClusHI, 0); /* cluster = 0 */ + ST_WORD(dir+DIR_FstClusLO, 0); + ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */ + dj.fs->wflag = 1; + ps = dj.fs->winsect; /* Remove the cluster chain */ + if (cl) { + res = remove_chain(dj.fs, cl); + if (res) LEAVE_FF(dj.fs, res); + dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */ + } + res = move_window(dj.fs, ps); + if (res != FR_OK) LEAVE_FF(dj.fs, res); + } + } + if (mode & FA_CREATE_ALWAYS) { + dir[DIR_Attr] = 0; /* Reset attribute */ + ps = get_fattime(); + ST_DWORD(dir+DIR_CrtTime, ps); /* Created time */ + dj.fs->wflag = 1; + mode |= FA__WRITTEN; /* Set file changed flag */ + } + } + /* Open an existing file */ + else { +#endif /* !_FS_READONLY */ + if (res != FR_OK) LEAVE_FF(dj.fs, res); /* Follow failed */ + dir = dj.dir; + if (!dir || (dir[DIR_Attr] & AM_DIR)) /* It is a directory */ + LEAVE_FF(dj.fs, FR_NO_FILE); +#if !_FS_READONLY + if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */ + LEAVE_FF(dj.fs, FR_DENIED); + } + fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */ + fp->dir_ptr = dj.dir; +#endif + fp->flag = mode; /* File access mode */ + fp->org_clust = /* File start cluster */ + ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */ + fp->fptr = 0; fp->csect = 255; /* File pointer */ + fp->dsect = 0; + fp->fs = dj.fs; fp->id = dj.fs->id; /* Owner file system object of the file */ + + LEAVE_FF(dj.fs, FR_OK); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_read ( + FIL *fp, /* Pointer to the file object */ + void *buff, /* Pointer to data buffer */ + UINT btr, /* Number of bytes to read */ + UINT *br /* Pointer to number of bytes read */ +) +{ + FRESULT res; + DWORD clst, sect, remain; + UINT rcnt, cc; + BYTE *rbuff = buff; + + + *br = 0; /* Initialize bytes read */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr; /* Repeat until all data transferred */ + rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + if (fp->csect >= fp->fs->csize) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->org_clust : get_fat(fp->fs, fp->curr_clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + fp->csect = 0; /* Reset sector offset in the cluster */ + } + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += fp->csect; + cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Read maximum contiguous sectors directly */ + if (fp->csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - fp->csect; + if (disk_read(fp->fs->drive, rbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if !_FS_READONLY && _FS_MINIMIZE <= 2 +#if _FS_TINY + if (fp->fs->wflag && fp->fs->winsect - sect < cc) /* Replace one of the read sectors with cached data if it contains a dirty sector */ + mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs)); +#else + if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc) /* Replace one of the read sectors with cached data if it contains a dirty sector */ + mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs)); +#endif +#endif + fp->csect += (BYTE)cc; /* Next sector address in the cluster */ + rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write sector I/O buffer if needed */ + if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (fp->dsect != sect) { /* Fill sector buffer with file data */ + if (disk_read(fp->fs->drive, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + fp->csect++; /* Next sector address in the cluster */ + } + rcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */ + if (rcnt > btr) rcnt = btr; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#else + mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#endif + } + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Write File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_write ( + FIL *fp, /* Pointer to the file object */ + const void *buff, /* Pointer to the data to be written */ + UINT btw, /* Number of bytes to write */ + UINT *bw /* Pointer to number of bytes written */ +) +{ + FRESULT res; + DWORD clst, sect; + UINT wcnt, cc; + const BYTE *wbuff = buff; + + + *bw = 0; /* Initialize bytes written */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + if (fp->fsize + btw < fp->fsize) btw = 0; /* File size cannot reach 4GB */ + + for ( ; btw; /* Repeat until all data transferred */ + wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + if (fp->csect >= fp->fs->csize) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->org_clust; /* Follow from the origin */ + if (clst == 0) /* When there is no cluster chain, */ + fp->org_clust = clst = create_chain(fp->fs, 0); /* Create a new cluster chain */ + } else { /* Middle or end of the file */ + clst = create_chain(fp->fs, fp->curr_clust); /* Follow or streach cluster chain */ + } + if (clst == 0) break; /* Could not allocate a new cluster (disk full) */ + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + fp->csect = 0; /* Reset sector address in the cluster */ + } +#if _FS_TINY + if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0)) /* Write back data buffer prior to following direct transfer */ + ABORT(fp->fs, FR_DISK_ERR); +#else + if (fp->flag & FA__DIRTY) { /* Write back data buffer prior to following direct transfer */ + if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += fp->csect; + cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Write maximum contiguous sectors directly */ + if (fp->csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - fp->csect; + if (disk_write(fp->fs->drive, wbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if _FS_TINY + if (fp->fs->winsect - sect < cc) { /* Refill sector cache if it gets dirty by the direct write */ + mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->fs->wflag = 0; + } +#else + if (fp->dsect - sect < cc) { /* Refill sector cache if it gets dirty by the direct write */ + mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->flag &= ~FA__DIRTY; + } +#endif + fp->csect += (BYTE)cc; /* Next sector address in the cluster */ + wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if _FS_TINY + if (fp->fptr >= fp->fsize) { /* Avoid silly buffer filling at growing edge */ + if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR); + fp->fs->winsect = sect; + } +#else + if (fp->dsect != sect) { /* Fill sector buffer with file data */ + if (fp->fptr < fp->fsize && + disk_read(fp->fs->drive, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + fp->csect++; /* Next sector address in the cluster */ + } + wcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Put partial sector into file I/O buffer */ + if (wcnt > btw) wcnt = btw; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->fs->wflag = 1; +#else + mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->flag |= FA__DIRTY; +#endif + } + + if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */ + fp->flag |= FA__WRITTEN; /* Set file changed flag */ + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Synchronize the File Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_sync ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD tim; + BYTE *dir; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__WRITTEN) { /* Has the file been written? */ +#if !_FS_TINY /* Write-back dirty buffer */ + if (fp->flag & FA__DIRTY) { + if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK) + LEAVE_FF(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + /* Update the directory entry */ + res = move_window(fp->fs, fp->dir_sect); + if (res == FR_OK) { + dir = fp->dir_ptr; + dir[DIR_Attr] |= AM_ARC; /* Set archive bit */ + ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */ + ST_WORD(dir+DIR_FstClusLO, fp->org_clust); /* Update start cluster */ + ST_WORD(dir+DIR_FstClusHI, fp->org_clust >> 16); + tim = get_fattime(); /* Updated time */ + ST_DWORD(dir+DIR_WrtTime, tim); + fp->flag &= ~FA__WRITTEN; + fp->fs->wflag = 1; + res = sync(fp->fs); + } + } + } + + LEAVE_FF(fp->fs, res); +} + +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Close File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_close ( + FIL *fp /* Pointer to the file object to be closed */ +) +{ + FRESULT res; + + +#if _FS_READONLY + res = validate(fp->fs, fp->id); + if (res == FR_OK) fp->fs = NULL; + LEAVE_FF(fp->fs, res); +#else + res = f_sync(fp); + if (res == FR_OK) fp->fs = NULL; + return res; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Current Drive/Directory */ +/*-----------------------------------------------------------------------*/ + +#if _FS_RPATH + +FRESULT f_chdrive ( + BYTE drv /* Drive number */ +) +{ + if (drv >= _DRIVES) return FR_INVALID_DRIVE; + + Drive = drv; + + return FR_OK; +} + + + + +FRESULT f_chdir ( + const XCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + NAMEBUF(sfn, lfn); + BYTE *dir; + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) { /* Follow completed */ + dir = dj.dir; /* Pointer to the entry */ + if (!dir) { + dj.fs->cdir = 0; /* No entry (root dir) */ + } else { + if (dir[DIR_Attr] & AM_DIR) /* Reached to the dir */ + dj.fs->cdir = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + else + res = FR_NO_PATH; /* Could not reach the dir (it is a file) */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj.fs, res); +} + +#endif + + + +#if _FS_MINIMIZE <= 2 +/*-----------------------------------------------------------------------*/ +/* Seek File R/W Pointer */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_lseek ( + FIL *fp, /* Pointer to the file object */ + DWORD ofs /* File pointer from top of file */ +) +{ + FRESULT res; + DWORD clst, bcs, nsect, ifptr; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */ +#if !_FS_READONLY + && !(fp->flag & FA_WRITE) +#endif + ) ofs = fp->fsize; + + ifptr = fp->fptr; + fp->fptr = nsect = 0; fp->csect = 255; + if (ofs > 0) { + bcs = (DWORD)fp->fs->csize * SS(fp->fs); /* Cluster size (byte) */ + if (ifptr > 0 && + (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ + fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */ + ofs -= fp->fptr; + clst = fp->curr_clust; + } else { /* When seek to back cluster, */ + clst = fp->org_clust; /* start from the first cluster */ +#if !_FS_READONLY + if (clst == 0) { /* If no cluster chain, create a new chain */ + clst = create_chain(fp->fs, 0); + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->org_clust = clst; + } +#endif + fp->curr_clust = clst; + } + if (clst != 0) { + while (ofs > bcs) { /* Cluster following loop */ +#if !_FS_READONLY + if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ + clst = create_chain(fp->fs, clst); /* Force streached if in write mode */ + if (clst == 0) { /* When disk gets full, clip file size */ + ofs = bcs; break; + } + } else +#endif + clst = get_fat(fp->fs, clst); /* Follow cluster chain if not in write mode */ + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + if (clst <= 1 || clst >= fp->fs->max_clust) ABORT(fp->fs, FR_INT_ERR); + fp->curr_clust = clst; + fp->fptr += bcs; + ofs -= bcs; + } + fp->fptr += ofs; + fp->csect = (BYTE)(ofs / SS(fp->fs)); /* Sector offset in the cluster */ + if (ofs % SS(fp->fs)) { + nsect = clust2sect(fp->fs, clst); /* Current sector */ + if (!nsect) ABORT(fp->fs, FR_INT_ERR); + nsect += fp->csect; + fp->csect++; + } + } + } + if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write-back dirty buffer if needed */ + if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drive, fp->buf, nsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = nsect; + } +#if !_FS_READONLY + if (fp->fptr > fp->fsize) { /* Set changed flag if the file size is extended */ + fp->fsize = fp->fptr; + fp->flag |= FA__WRITTEN; + } +#endif + + LEAVE_FF(fp->fs, res); +} + + + + +#if _FS_MINIMIZE <= 1 +/*-----------------------------------------------------------------------*/ +/* Create a Directroy Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_opendir ( + DIR *dj, /* Pointer to directory object to create */ + const XCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + NAMEBUF(sfn, lfn); + BYTE *dir; + + + res = chk_mounted(&path, &dj->fs, 0); + if (res == FR_OK) { + INITBUF((*dj), sfn, lfn); + res = follow_path(dj, path); /* Follow the path to the directory */ + if (res == FR_OK) { /* Follow completed */ + dir = dj->dir; + if (dir) { /* It is not the root dir */ + if (dir[DIR_Attr] & AM_DIR) { /* The object is a directory */ + dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + } else { /* The object is not a directory */ + res = FR_NO_PATH; + } + } + if (res == FR_OK) { + dj->id = dj->fs->id; + res = dir_seek(dj, 0); /* Rewind dir */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read Directory Entry in Sequense */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_readdir ( + DIR *dj, /* Pointer to the open directory object */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + NAMEBUF(sfn, lfn); + + + res = validate(dj->fs, dj->id); /* Check validity of the object */ + if (res == FR_OK) { + INITBUF((*dj), sfn, lfn); + if (!fno) { + res = dir_seek(dj, 0); + } else { + res = dir_read(dj); + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + if (res == FR_OK) { /* A valid entry is found */ + get_fileinfo(dj, fno); /* Get the object information */ + res = dir_next(dj, FALSE); /* Increment index for next */ + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + } + } + } + + LEAVE_FF(dj->fs, res); +} + + + +#if _FS_MINIMIZE == 0 +/*-----------------------------------------------------------------------*/ +/* Get File Status */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_stat ( + const XCHAR *path, /* Pointer to the file path */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DIR dj; + NAMEBUF(sfn, lfn); + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) { /* Follwo completed */ + if (dj.dir) /* Found an object */ + get_fileinfo(&dj, fno); + else /* It is root dir */ + res = FR_INVALID_NAME; + } + } + + LEAVE_FF(dj.fs, res); +} + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Get Number of Free Clusters */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getfree ( + const XCHAR *path, /* Pointer to the logical drive number (root dir) */ + DWORD *nclst, /* Pointer to the variable to return number of free clusters */ + FATFS **fatfs /* Pointer to pointer to corresponding file system object to return */ +) +{ + FRESULT res; + DWORD n, clst, sect, stat; + UINT i; + BYTE fat, *p; + + + /* Get drive number */ + res = chk_mounted(&path, fatfs, 0); + if (res != FR_OK) LEAVE_FF(*fatfs, res); + + /* If number of free cluster is valid, return it without cluster scan. */ + if ((*fatfs)->free_clust <= (*fatfs)->max_clust - 2) { + *nclst = (*fatfs)->free_clust; + LEAVE_FF(*fatfs, FR_OK); + } + + /* Get number of free clusters */ + fat = (*fatfs)->fs_type; + n = 0; + if (fat == FS_FAT12) { + clst = 2; + do { + stat = get_fat(*fatfs, clst); + if (stat == 0xFFFFFFFF) LEAVE_FF(*fatfs, FR_DISK_ERR); + if (stat == 1) LEAVE_FF(*fatfs, FR_INT_ERR); + if (stat == 0) n++; + } while (++clst < (*fatfs)->max_clust); + } else { + clst = (*fatfs)->max_clust; + sect = (*fatfs)->fatbase; + i = 0; p = 0; + do { + if (!i) { + res = move_window(*fatfs, sect++); + if (res != FR_OK) + LEAVE_FF(*fatfs, res); + p = (*fatfs)->win; + i = SS(*fatfs); + } + if (fat == FS_FAT16) { + if (LD_WORD(p) == 0) n++; + p += 2; i -= 2; + } else { + if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++; + p += 4; i -= 4; + } + } while (--clst); + } + (*fatfs)->free_clust = n; + if (fat == FS_FAT32) (*fatfs)->fsi_flag = 1; + *nclst = n; + + LEAVE_FF(*fatfs, FR_OK); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Truncate File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_truncate ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD ncl; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + + if (fp->fsize > fp->fptr) { + fp->fsize = fp->fptr; /* Set file size to current R/W point */ + fp->flag |= FA__WRITTEN; + if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */ + res = remove_chain(fp->fs, fp->org_clust); + fp->org_clust = 0; + } else { /* When truncate a part of the file, remove remaining clusters */ + ncl = get_fat(fp->fs, fp->curr_clust); + res = FR_OK; + if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (ncl == 1) res = FR_INT_ERR; + if (res == FR_OK && ncl < fp->fs->max_clust) { + res = put_fat(fp->fs, fp->curr_clust, 0x0FFFFFFF); + if (res == FR_OK) res = remove_chain(fp->fs, ncl); + } + } + } + if (res != FR_OK) fp->flag |= FA__ERROR; + + LEAVE_FF(fp->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Delete a File or Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_unlink ( + const XCHAR *path /* Pointer to the file or directory path */ +) +{ + FRESULT res; + DIR dj, sdj; + NAMEBUF(sfn, lfn); + BYTE *dir; + DWORD dclst; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res != FR_OK) LEAVE_FF(dj.fs, res); + + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res != FR_OK) LEAVE_FF(dj.fs, res); /* Follow failed */ + + dir = dj.dir; + if (!dir) /* Is it the root directory? */ + LEAVE_FF(dj.fs, FR_INVALID_NAME); + if (dir[DIR_Attr] & AM_RDO) /* Is it a R/O object? */ + LEAVE_FF(dj.fs, FR_DENIED); + dclst = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + + if (dir[DIR_Attr] & AM_DIR) { /* It is a sub-directory */ + if (dclst < 2) LEAVE_FF(dj.fs, FR_INT_ERR); + mem_cpy(&sdj, &dj, sizeof(DIR)); /* Check if the sub-dir is empty or not */ + sdj.sclust = dclst; + res = dir_seek(&sdj, 2); + if (res != FR_OK) LEAVE_FF(dj.fs, res); + res = dir_read(&sdj); + if (res == FR_OK) res = FR_DENIED; /* Not empty sub-dir */ + if (res != FR_NO_FILE) LEAVE_FF(dj.fs, res); + } + + res = dir_remove(&dj); /* Remove directory entry */ + if (res == FR_OK) { + if (dclst) + res = remove_chain(dj.fs, dclst); /* Remove the cluster chain */ + if (res == FR_OK) res = sync(dj.fs); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Create a Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mkdir ( + const XCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + NAMEBUF(sfn, lfn); + BYTE *dir, n; + DWORD dsect, dclst, pclst, tim; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res != FR_OK) LEAVE_FF(dj.fs, res); + + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) res = FR_EXIST; /* Any file or directory is already existing */ + if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res != FR_NO_FILE) /* Any error occured */ + LEAVE_FF(dj.fs, res); + + dclst = create_chain(dj.fs, 0); /* Allocate a new cluster for new directory table */ + res = FR_OK; + if (dclst == 0) res = FR_DENIED; + if (dclst == 1) res = FR_INT_ERR; + if (dclst == 0xFFFFFFFF) res = FR_DISK_ERR; + if (res == FR_OK) + res = move_window(dj.fs, 0); + if (res != FR_OK) LEAVE_FF(dj.fs, res); + dsect = clust2sect(dj.fs, dclst); + + dir = dj.fs->win; /* Initialize the new directory table */ + mem_set(dir, 0, SS(dj.fs)); + mem_set(dir+DIR_Name, ' ', 8+3); /* Create "." entry */ + dir[DIR_Name] = '.'; + dir[DIR_Attr] = AM_DIR; + tim = get_fattime(); + ST_DWORD(dir+DIR_WrtTime, tim); + ST_WORD(dir+DIR_FstClusLO, dclst); + ST_WORD(dir+DIR_FstClusHI, dclst >> 16); + mem_cpy(dir+32, dir, 32); /* Create ".." entry */ + dir[33] = '.'; + pclst = dj.sclust; + if (dj.fs->fs_type == FS_FAT32 && pclst == dj.fs->dirbase) + pclst = 0; + ST_WORD(dir+32+DIR_FstClusLO, pclst); + ST_WORD(dir+32+DIR_FstClusHI, pclst >> 16); + for (n = 0; n < dj.fs->csize; n++) { /* Write dot entries and clear left sectors */ + dj.fs->winsect = dsect++; + dj.fs->wflag = 1; + res = move_window(dj.fs, 0); + if (res) LEAVE_FF(dj.fs, res); + mem_set(dir, 0, SS(dj.fs)); + } + + res = dir_register(&dj); + if (res != FR_OK) { + remove_chain(dj.fs, dclst); + } else { + dir = dj.dir; + dir[DIR_Attr] = AM_DIR; /* Attribute */ + ST_DWORD(dir+DIR_WrtTime, tim); /* Crated time */ + ST_WORD(dir+DIR_FstClusLO, dclst); /* Table start cluster */ + ST_WORD(dir+DIR_FstClusHI, dclst >> 16); + dj.fs->wflag = 1; + res = sync(dj.fs); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change File Attribute */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_chmod ( + const XCHAR *path, /* Pointer to the file path */ + BYTE value, /* Attribute bits */ + BYTE mask /* Attribute mask to change */ +) +{ + FRESULT res; + DIR dj; + NAMEBUF(sfn, lfn); + BYTE *dir; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Is it a root directory? */ + res = FR_INVALID_NAME; + } else { /* File or sub directory */ + mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ + dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Timestamp */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_utime ( + const XCHAR *path, /* Pointer to the file/directory name */ + const FILINFO *fno /* Pointer to the timestamp to be set */ +) +{ + FRESULT res; + DIR dj; + NAMEBUF(sfn, lfn); + BYTE *dir; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Root directory */ + res = FR_INVALID_NAME; + } else { /* File or sub-directory */ + ST_WORD(dir+DIR_WrtTime, fno->ftime); + ST_WORD(dir+DIR_WrtDate, fno->fdate); + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Rename File/Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_rename ( + const XCHAR *path_old, /* Pointer to the old name */ + const XCHAR *path_new /* Pointer to the new name */ +) +{ + FRESULT res; + DIR dj_old, dj_new; + NAMEBUF(sfn, lfn); + BYTE buf[21], *dir; + DWORD dw; + + + INITBUF(dj_old, sfn, lfn); + res = chk_mounted(&path_old, &dj_old.fs, 1); + if (res == FR_OK) { + dj_new.fs = dj_old.fs; + res = follow_path(&dj_old, path_old); /* Check old object */ + if (_FS_RPATH && res == FR_OK && (dj_old.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + } + if (res != FR_OK) LEAVE_FF(dj_old.fs, res); /* The old object is not found */ + + if (!dj_old.dir) LEAVE_FF(dj_old.fs, FR_NO_FILE); /* Is root dir? */ + mem_cpy(buf, dj_old.dir+DIR_Attr, 21); /* Save the object information */ + + mem_cpy(&dj_new, &dj_old, sizeof(DIR)); + res = follow_path(&dj_new, path_new); /* Check new object */ + if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */ + if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */ + res = dir_register(&dj_new); /* Register the new object */ + if (res == FR_OK) { + dir = dj_new.dir; /* Copy object information into new entry */ + mem_cpy(dir+13, buf+2, 19); + dir[DIR_Attr] = buf[0] | AM_ARC; + dj_old.fs->wflag = 1; + if (dir[DIR_Attr] & AM_DIR) { /* Update .. entry in the directory if needed */ + dw = clust2sect(dj_new.fs, (DWORD)LD_WORD(dir+DIR_FstClusHI) | LD_WORD(dir+DIR_FstClusLO)); + if (!dw) { + res = FR_INT_ERR; + } else { + res = move_window(dj_new.fs, dw); + dir = dj_new.fs->win+32; + if (res == FR_OK && dir[1] == '.') { + dw = (dj_new.fs->fs_type == FS_FAT32 && dj_new.sclust == dj_new.fs->dirbase) ? 0 : dj_new.sclust; + ST_WORD(dir+DIR_FstClusLO, dw); + ST_WORD(dir+DIR_FstClusHI, dw >> 16); + dj_new.fs->wflag = 1; + } + } + } + if (res == FR_OK) { + res = dir_remove(&dj_old); /* Remove old entry */ + if (res == FR_OK) + res = sync(dj_old.fs); + } + } + } + + LEAVE_FF(dj_old.fs, res); +} + +#endif /* !_FS_READONLY */ +#endif /* _FS_MINIMIZE == 0 */ +#endif /* _FS_MINIMIZE <= 1 */ +#endif /* _FS_MINIMIZE <= 2 */ + + + +/*-----------------------------------------------------------------------*/ +/* Forward data to the stream directly (Available on only _FS_TINY cfg) */ +/*-----------------------------------------------------------------------*/ +#if _USE_FORWARD && _FS_TINY + +FRESULT f_forward ( + FIL *fp, /* Pointer to the file object */ + UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */ + UINT btr, /* Number of bytes to forward */ + UINT *bf /* Pointer to number of bytes forwarded */ +) +{ + FRESULT res; + DWORD remain, clst, sect; + UINT rcnt; + + + *bf = 0; + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check error flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr && (*func)(NULL, 0); /* Repeat until all data transferred or stream becomes busy */ + fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + if (fp->csect >= fp->fs->csize) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->org_clust : get_fat(fp->fs, fp->curr_clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + fp->csect = 0; /* Reset sector address in the cluster */ + } + fp->csect++; /* Next sector address in the cluster */ + } + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current data sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += fp->csect - 1; + if (move_window(fp->fs, sect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + fp->dsect = sect; + rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs)); /* Forward data from sector window */ + if (rcnt > btr) rcnt = btr; + rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt); + if (!rcnt) ABORT(fp->fs, FR_INT_ERR); + } + + LEAVE_FF(fp->fs, FR_OK); +} +#endif /* _USE_FORWARD */ + + + +#if _USE_MKFS && !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Create File System on the Drive */ +/*-----------------------------------------------------------------------*/ +#define N_ROOTDIR 512 /* Multiple of 32 and <= 2048 */ +#define N_FATS 1 /* 1 or 2 */ +#define MAX_SECTOR 131072000UL /* Maximum partition size */ +#define MIN_SECTOR 2000UL /* Minimum partition size */ + + +FRESULT f_mkfs ( + BYTE drv, /* Logical drive number */ + BYTE partition, /* Partitioning rule 0:FDISK, 1:SFD */ + WORD allocsize /* Allocation unit size [bytes] */ +) +{ + static const DWORD sstbl[] = { 2048000, 1024000, 512000, 256000, 128000, 64000, 32000, 16000, 8000, 4000, 0 }; + static const WORD cstbl[] = { 32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512 }; + BYTE fmt, m, *tbl; + DWORD b_part, b_fat, b_dir, b_data; /* Area offset (LBA) */ + DWORD n_part, n_rsv, n_fat, n_dir; /* Area size */ + DWORD n_clst, d, n; + WORD as; + FATFS *fs; + DSTATUS stat; + + + /* Check validity of the parameters */ + if (drv >= _DRIVES) return FR_INVALID_DRIVE; + if (partition >= 2) return FR_MKFS_ABORTED; + + /* Check mounted drive and clear work area */ + fs = FatFs[drv]; + if (!fs) return FR_NOT_ENABLED; + fs->fs_type = 0; + drv = LD2PD(drv); + + /* Get disk statics */ + stat = disk_initialize(drv); + if (stat & STA_NOINIT) return FR_NOT_READY; + if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; +#if _MAX_SS != 512 /* Get disk sector size */ + if (disk_ioctl(drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK + || SS(fs) > _MAX_SS) + return FR_MKFS_ABORTED; +#endif + if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_part) != RES_OK || n_part < MIN_SECTOR) + return FR_MKFS_ABORTED; + if (n_part > MAX_SECTOR) n_part = MAX_SECTOR; + b_part = (!partition) ? 63 : 0; /* Boot sector */ + n_part -= b_part; + for (d = 512; d <= 32768U && d != allocsize; d <<= 1) ; /* Check validity of the allocation unit size */ + if (d != allocsize) allocsize = 0; + if (!allocsize) { /* Auto selection of cluster size */ + d = n_part; + for (as = SS(fs); as > 512U; as >>= 1) d >>= 1; + for (n = 0; d < sstbl[n]; n++) ; + allocsize = cstbl[n]; + } + if (allocsize < SS(fs)) allocsize = SS(fs); + + allocsize /= SS(fs); /* Number of sectors per cluster */ + + /* Pre-compute number of clusters and FAT type */ + n_clst = n_part / allocsize; + fmt = FS_FAT12; + if (n_clst >= 0xFF5) fmt = FS_FAT16; + if (n_clst >= 0xFFF5) fmt = FS_FAT32; + + /* Determine offset and size of FAT structure */ + switch (fmt) { + case FS_FAT12: + n_fat = ((n_clst * 3 + 1) / 2 + 3 + SS(fs) - 1) / SS(fs); + n_rsv = 1 + partition; + n_dir = N_ROOTDIR * 32 / SS(fs); + break; + case FS_FAT16: + n_fat = ((n_clst * 2) + 4 + SS(fs) - 1) / SS(fs); + n_rsv = 1 + partition; + n_dir = N_ROOTDIR * 32 / SS(fs); + break; + default: + n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs); + n_rsv = 33 - partition; + n_dir = 0; + } + b_fat = b_part + n_rsv; /* FATs start sector */ + b_dir = b_fat + n_fat * N_FATS; /* Directory start sector */ + b_data = b_dir + n_dir; /* Data start sector */ + + /* Align data start sector to erase block boundary (for flash memory media) */ + if (disk_ioctl(drv, GET_BLOCK_SIZE, &n) != RES_OK) return FR_MKFS_ABORTED; + n = (b_data + n - 1) & ~(n - 1); + n_fat += (n - b_data) / N_FATS; + /* b_dir and b_data are no longer used below */ + + /* Determine number of cluster and final check of validity of the FAT type */ + n_clst = (n_part - n_rsv - n_fat * N_FATS - n_dir) / allocsize; + if ( (fmt == FS_FAT16 && n_clst < 0xFF5) + || (fmt == FS_FAT32 && n_clst < 0xFFF5)) + return FR_MKFS_ABORTED; + + /* Create partition table if needed */ + if (!partition) { + DWORD n_disk = b_part + n_part; + + mem_set(fs->win, 0, SS(fs)); + tbl = fs->win+MBR_Table; + ST_DWORD(tbl, 0x00010180); /* Partition start in CHS */ + if (n_disk < 63UL * 255 * 1024) { /* Partition end in CHS */ + n_disk = n_disk / 63 / 255; + tbl[7] = (BYTE)n_disk; + tbl[6] = (BYTE)((n_disk >> 2) | 63); + } else { + ST_WORD(&tbl[6], 0xFFFF); + } + tbl[5] = 254; + if (fmt != FS_FAT32) /* System ID */ + tbl[4] = (n_part < 0x10000) ? 0x04 : 0x06; + else + tbl[4] = 0x0c; + ST_DWORD(tbl+8, 63); /* Partition start in LBA */ + ST_DWORD(tbl+12, n_part); /* Partition size in LBA */ + ST_WORD(tbl+64, 0xAA55); /* Signature */ + if (disk_write(drv, fs->win, 0, 1) != RES_OK) + return FR_DISK_ERR; + partition = 0xF8; + } else { + partition = 0xF0; + } + + /* Create boot record */ + tbl = fs->win; /* Clear buffer */ + mem_set(tbl, 0, SS(fs)); + ST_DWORD(tbl+BS_jmpBoot, 0x90FEEB); /* Boot code (jmp $, nop) */ + ST_WORD(tbl+BPB_BytsPerSec, SS(fs)); /* Sector size */ + tbl[BPB_SecPerClus] = (BYTE)allocsize; /* Sectors per cluster */ + ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */ + tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */ + ST_WORD(tbl+BPB_RootEntCnt, SS(fs) / 32 * n_dir); /* Number of rootdir entries */ + if (n_part < 0x10000) { /* Number of total sectors */ + ST_WORD(tbl+BPB_TotSec16, n_part); + } else { + ST_DWORD(tbl+BPB_TotSec32, n_part); + } + tbl[BPB_Media] = partition; /* Media descripter */ + ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */ + ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */ + ST_DWORD(tbl+BPB_HiddSec, b_part); /* Hidden sectors */ + n = get_fattime(); /* Use current time as a VSN */ + if (fmt != FS_FAT32) { + ST_DWORD(tbl+BS_VolID, n); /* Volume serial number */ + ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of secters per FAT */ + tbl[BS_DrvNum] = 0x80; /* Drive number */ + tbl[BS_BootSig] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab, "NO NAME FAT ", 19); /* Volume lavel, FAT signature */ + } else { + ST_DWORD(tbl+BS_VolID32, n); /* Volume serial number */ + ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of secters per FAT */ + ST_DWORD(tbl+BPB_RootClus, 2); /* Root directory cluster (2) */ + ST_WORD(tbl+BPB_FSInfo, 1); /* FSInfo record offset (bs+1) */ + ST_WORD(tbl+BPB_BkBootSec, 6); /* Backup boot record offset (bs+6) */ + tbl[BS_DrvNum32] = 0x80; /* Drive number */ + tbl[BS_BootSig32] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab32, "NO NAME FAT32 ", 19); /* Volume lavel, FAT signature */ + } + ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature */ + if (SS(fs) > 512U) { + ST_WORD(tbl+SS(fs)-2, 0xAA55); + } + if (disk_write(drv, tbl, b_part+0, 1) != RES_OK) + return FR_DISK_ERR; + if (fmt == FS_FAT32) + disk_write(drv, tbl, b_part+6, 1); + + /* Initialize FAT area */ + for (m = 0; m < N_FATS; m++) { + mem_set(tbl, 0, SS(fs)); /* 1st sector of the FAT */ + if (fmt != FS_FAT32) { + n = (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00; + n |= partition; + ST_DWORD(tbl, n); /* Reserve cluster #0-1 (FAT12/16) */ + } else { + ST_DWORD(tbl+0, 0xFFFFFFF8); /* Reserve cluster #0-1 (FAT32) */ + ST_DWORD(tbl+4, 0xFFFFFFFF); + ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root dir */ + } + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + mem_set(tbl, 0, SS(fs)); /* Following FAT entries are filled by zero */ + for (n = 1; n < n_fat; n++) { + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + } + } + + /* Initialize Root directory */ + m = (BYTE)((fmt == FS_FAT32) ? allocsize : n_dir); + do { + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + } while (--m); + + /* Create FSInfo record if needed */ + if (fmt == FS_FAT32) { + ST_WORD(tbl+BS_55AA, 0xAA55); + ST_DWORD(tbl+FSI_LeadSig, 0x41615252); + ST_DWORD(tbl+FSI_StrucSig, 0x61417272); + ST_DWORD(tbl+FSI_Free_Count, n_clst - 1); + ST_DWORD(tbl+FSI_Nxt_Free, 0xFFFFFFFF); + disk_write(drv, tbl, b_part+1, 1); + disk_write(drv, tbl, b_part+7, 1); + } + + return (disk_ioctl(drv, CTRL_SYNC, (void*)NULL) == RES_OK) ? FR_OK : FR_DISK_ERR; +} + +#endif /* _USE_MKFS && !_FS_READONLY */ + + + + +#if _USE_STRFUNC +/*-----------------------------------------------------------------------*/ +/* Get a string from the file */ +/*-----------------------------------------------------------------------*/ +char* f_gets ( + char* buff, /* Pointer to the string buffer to read */ + int len, /* Size of string buffer */ + FIL* fil /* Pointer to the file object */ +) +{ + int i = 0; + char *p = buff; + UINT rc; + + + while (i < len - 1) { /* Read bytes until buffer gets filled */ + f_read(fil, p, 1, &rc); + if (rc != 1) break; /* Break when no data to read */ +#if _USE_STRFUNC >= 2 + if (*p == '\r') continue; /* Strip '\r' */ +#endif + i++; + if (*p++ == '\n') break; /* Break when reached end of line */ + } + *p = 0; + return i ? buff : NULL; /* When no data read (eof or error), return with error. */ +} + + + +#if !_FS_READONLY +#include +/*-----------------------------------------------------------------------*/ +/* Put a character to the file */ +/*-----------------------------------------------------------------------*/ +int f_putc ( + int chr, /* A character to be output */ + FIL* fil /* Ponter to the file object */ +) +{ + UINT bw; + char c; + + +#if _USE_STRFUNC >= 2 + if (chr == '\n') f_putc ('\r', fil); /* LF -> CRLF conversion */ +#endif + if (!fil) { /* Special value may be used to switch the destination to any other device */ + /* put_console(chr); */ + return chr; + } + c = (char)chr; + f_write(fil, &c, 1, &bw); /* Write a byte to the file */ + return bw ? chr : EOF; /* Return the result */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a string to the file */ +/*-----------------------------------------------------------------------*/ +int f_puts ( + const char* str, /* Pointer to the string to be output */ + FIL* fil /* Pointer to the file object */ +) +{ + int n; + + + for (n = 0; *str; str++, n++) { + if (f_putc(*str, fil) == EOF) return EOF; + } + return n; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a formatted string to the file */ +/*-----------------------------------------------------------------------*/ +int f_printf ( + FIL* fil, /* Pointer to the file object */ + const char* str, /* Pointer to the format string */ + ... /* Optional arguments... */ +) +{ + va_list arp; + UCHAR c, f, r; + ULONG val; + char s[16]; + int i, w, res, cc; + + + va_start(arp, str); + + for (cc = res = 0; cc != EOF; res += cc) { + c = *str++; + if (c == 0) break; /* End of string */ + if (c != '%') { /* Non escape cahracter */ + cc = f_putc(c, fil); + if (cc != EOF) cc = 1; + continue; + } + w = f = 0; + c = *str++; + if (c == '0') { /* Flag: '0' padding */ + f = 1; c = *str++; + } + while (c >= '0' && c <= '9') { /* Precision */ + w = w * 10 + (c - '0'); + c = *str++; + } + if (c == 'l') { /* Prefix: Size is long int */ + f |= 2; c = *str++; + } + if (c == 's') { /* Type is string */ + cc = f_puts(va_arg(arp, char*), fil); + continue; + } + if (c == 'c') { /* Type is character */ + cc = f_putc(va_arg(arp, int), fil); + if (cc != EOF) cc = 1; + continue; + } + r = 0; + if (c == 'd') r = 10; /* Type is signed decimal */ + if (c == 'u') r = 10; /* Type is unsigned decimal */ + if (c == 'X') r = 16; /* Type is unsigned hexdecimal */ + if (r == 0) break; /* Unknown type */ + if (f & 2) { /* Get the value */ + val = (ULONG)va_arg(arp, long); + } else { + val = (c == 'd') ? (ULONG)(long)va_arg(arp, int) : (ULONG)va_arg(arp, unsigned int); + } + /* Put numeral string */ + if (c == 'd') { + if (val & 0x80000000) { + val = 0 - val; + f |= 4; + } + } + i = sizeof(s) - 1; s[i] = 0; + do { + c = (UCHAR)(val % r + '0'); + if (c > '9') c += 7; + s[--i] = c; + val /= r; + } while (i && val); + if (i && (f & 4)) s[--i] = '-'; + w = sizeof(s) - 1 - w; + while (i && i > w) s[--i] = (f & 1) ? '0' : ' '; + cc = f_puts(&s[i], fil); + } + + va_end(arp); + return (cc == EOF) ? cc : res; +} + +#endif /* !_FS_READONLY */ +#endif /* _USE_STRFUNC */ diff --git a/Projects/TemperatureDataLogger/Lib/FATFs/ff.h b/Projects/TemperatureDataLogger/Lib/FATFs/ff.h new file mode 100644 index 000000000..c24d6c7f3 --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/FATFs/ff.h @@ -0,0 +1,596 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module include file R0.07e (C)ChaN, 2009 +/----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following trems. +/ +/ Copyright (C) 2009, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/----------------------------------------------------------------------------*/ + +#ifndef _FATFS +#define _FATFS 0x007E + +#include "integer.h" /* Basic integer types */ +#include "ffconf.h" /* FatFs configuration options */ + +#if _FATFS != _FFCONFIG +#error Wrong configuration file (ffconf.h). +#endif + + +/* DBCS code ranges and SBCS extend char conversion table */ + +#if _CODE_PAGE == 932 /* Japanese Shift-JIS */ +#define _DF1S 0x81 /* DBC 1st byte range 1 start */ +#define _DF1E 0x9F /* DBC 1st byte range 1 end */ +#define _DF2S 0xE0 /* DBC 1st byte range 2 start */ +#define _DF2E 0xFC /* DBC 1st byte range 2 end */ +#define _DS1S 0x40 /* DBC 2nd byte range 1 start */ +#define _DS1E 0x7E /* DBC 2nd byte range 1 end */ +#define _DS2S 0x80 /* DBC 2nd byte range 2 start */ +#define _DS2E 0xFC /* DBC 2nd byte range 2 end */ + +#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0x80 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 949 /* Korean */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x41 +#define _DS1E 0x5A +#define _DS2S 0x61 +#define _DS2E 0x7A +#define _DS3S 0x81 +#define _DS3E 0xFE + +#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0xA1 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 437 /* U.S. (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 720 /* Arabic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 737 /* Greek (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 775 /* Baltic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} + +#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ + 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ + 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 857 /* Turkish (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 862 /* Hebrew (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 866 /* Russian (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF} + +#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1253 /* Greek (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \ + 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF} + +#elif _CODE_PAGE == 1254 /* Turkish (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1256 /* Arabic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1257 /* Baltic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F} + +#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */ +#define _DF1S 0 + +#else +#error Unknown code page + +#endif + + + +/* Character code support macros */ + +#define IsUpper(c) (((c)>='A')&&((c)<='Z')) +#define IsLower(c) (((c)>='a')&&((c)<='z')) + +#if _DF1S /* DBCS configuration */ + +#ifdef _DF2S /* Two 1st byte areas */ +#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E)) +#else /* One 1st byte area */ +#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) +#endif + +#ifdef _DS3S /* Three 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E)) +#else /* Two 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E)) +#endif + +#else /* SBCS configuration */ + +#define IsDBCS1(c) 0 +#define IsDBCS2(c) 0 + +#endif /* _DF1S */ + + + +/* Definitions corresponds to multi partition */ + +#if _MULTI_PARTITION /* Multiple partition configuration */ + +typedef struct _PARTITION { + BYTE pd; /* Physical drive# */ + BYTE pt; /* Partition # (0-3) */ +} PARTITION; + +extern +const PARTITION Drives[]; /* Logical drive# to physical location conversion table */ +#define LD2PD(drv) (Drives[drv].pd) /* Get physical drive# */ +#define LD2PT(drv) (Drives[drv].pt) /* Get partition# */ + +#else /* Single partition configuration */ + +#define LD2PD(drv) (drv) /* Physical drive# is equal to the logical drive# */ +#define LD2PT(drv) 0 /* Always mounts the 1st partition */ + +#endif + + + +/* Definitions corresponds to multiple sector size */ + +#if _MAX_SS == 512 /* Single sector size */ +#define SS(fs) 512U + +#elif _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096 /* Multiple sector size */ +#define SS(fs) ((fs)->s_size) + +#else +#error Sector size must be 512, 1024, 2048 or 4096. + +#endif + + + +/* Type of file name on FatFs API */ + +#if _LFN_UNICODE && _USE_LFN +typedef WCHAR XCHAR; /* Unicode */ +#else +typedef char XCHAR; /* SBCS, DBCS */ +#endif + + + +/* File system object structure */ + +typedef struct _FATFS_ { + BYTE fs_type; /* FAT sub type */ + BYTE drive; /* Physical drive number */ + BYTE csize; /* Number of sectors per cluster */ + BYTE n_fats; /* Number of FAT copies */ + BYTE wflag; /* win[] dirty flag (1:must be written back) */ + BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */ + WORD id; /* File system mount ID */ + WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */ +#if _FS_REENTRANT + _SYNC_t sobj; /* Identifier of sync object */ +#endif +#if _MAX_SS != 512 + WORD s_size; /* Sector size */ +#endif +#if !_FS_READONLY + DWORD last_clust; /* Last allocated cluster */ + DWORD free_clust; /* Number of free clusters */ + DWORD fsi_sector; /* fsinfo sector */ +#endif +#if _FS_RPATH + DWORD cdir; /* Current directory (0:root)*/ +#endif + DWORD sects_fat; /* Sectors per fat */ + DWORD max_clust; /* Maximum cluster# + 1. Number of clusters is max_clust - 2 */ + DWORD fatbase; /* FAT start sector */ + DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */ + DWORD database; /* Data start sector */ + DWORD winsect; /* Current sector appearing in the win[] */ + BYTE win[_MAX_SS];/* Disk access window for Directory/FAT */ +} FATFS; + + + +/* Directory object structure */ + +typedef struct _DIR_ { + FATFS* fs; /* Pointer to the owner file system object */ + WORD id; /* Owner file system mount ID */ + WORD index; /* Current read/write index number */ + DWORD sclust; /* Table start cluster (0:Static table) */ + DWORD clust; /* Current cluster */ + DWORD sect; /* Current sector */ + BYTE* dir; /* Pointer to the current SFN entry in the win[] */ + BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ +#if _USE_LFN + WCHAR* lfn; /* Pointer to the LFN working buffer */ + WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */ +#endif +} DIR; + + + +/* File object structure */ + +typedef struct _FIL_ { + FATFS* fs; /* Pointer to the owner file system object */ + WORD id; /* Owner file system mount ID */ + BYTE flag; /* File status flags */ + BYTE csect; /* Sector address in the cluster */ + DWORD fptr; /* File R/W pointer */ + DWORD fsize; /* File size */ + DWORD org_clust; /* File start cluster */ + DWORD curr_clust; /* Current cluster */ + DWORD dsect; /* Current data sector */ +#if !_FS_READONLY + DWORD dir_sect; /* Sector containing the directory entry */ + BYTE* dir_ptr; /* Ponter to the directory entry in the window */ +#endif +#if !_FS_TINY + BYTE buf[_MAX_SS];/* File R/W buffer */ +#endif +} FIL; + + + +/* File status structure */ + +typedef struct _FILINFO_ { + DWORD fsize; /* File size */ + WORD fdate; /* Last modified date */ + WORD ftime; /* Last modified time */ + BYTE fattrib; /* Attribute */ + char fname[13]; /* Short file name (8.3 format) */ +#if _USE_LFN + XCHAR* lfname; /* Pointer to the LFN buffer */ + int lfsize; /* Size of LFN buffer [chrs] */ +#endif +} FILINFO; + + + +/* File function return code (FRESULT) */ + +typedef enum { + FR_OK = 0, /* 0 */ + FR_DISK_ERR, /* 1 */ + FR_INT_ERR, /* 2 */ + FR_NOT_READY, /* 3 */ + FR_NO_FILE, /* 4 */ + FR_NO_PATH, /* 5 */ + FR_INVALID_NAME, /* 6 */ + FR_DENIED, /* 7 */ + FR_EXIST, /* 8 */ + FR_INVALID_OBJECT, /* 9 */ + FR_WRITE_PROTECTED, /* 10 */ + FR_INVALID_DRIVE, /* 11 */ + FR_NOT_ENABLED, /* 12 */ + FR_NO_FILESYSTEM, /* 13 */ + FR_MKFS_ABORTED, /* 14 */ + FR_TIMEOUT /* 15 */ +} FRESULT; + + + +/*--------------------------------------------------------------*/ +/* FatFs module application interface */ + +FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */ +FRESULT f_open (FIL*, const XCHAR*, BYTE); /* Open or create a file */ +FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */ +FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */ +FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */ +FRESULT f_close (FIL*); /* Close an open file object */ +FRESULT f_opendir (DIR*, const XCHAR*); /* Open an existing directory */ +FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */ +FRESULT f_stat (const XCHAR*, FILINFO*); /* Get file status */ +FRESULT f_getfree (const XCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */ +FRESULT f_truncate (FIL*); /* Truncate file */ +FRESULT f_sync (FIL*); /* Flush cached data of a writing file */ +FRESULT f_unlink (const XCHAR*); /* Delete an existing file or directory */ +FRESULT f_mkdir (const XCHAR*); /* Create a new directory */ +FRESULT f_chmod (const XCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */ +FRESULT f_utime (const XCHAR*, const FILINFO*); /* Change timestamp of the file/dir */ +FRESULT f_rename (const XCHAR*, const XCHAR*); /* Rename/Move a file or directory */ +FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */ +FRESULT f_mkfs (BYTE, BYTE, WORD); /* Create a file system on the drive */ +FRESULT f_chdir (const XCHAR*); /* Change current directory */ +FRESULT f_chdrive (BYTE); /* Change current drive */ + +#if _USE_STRFUNC +int f_putc (int, FIL*); /* Put a character to the file */ +int f_puts (const char*, FIL*); /* Put a string to the file */ +int f_printf (FIL*, const char*, ...); /* Put a formatted string to the file */ +char* f_gets (char*, int, FIL*); /* Get a string from the file */ +#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0) +#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0) +#ifndef EOF +#define EOF -1 +#endif +#endif + + + +/*--------------------------------------------------------------*/ +/* User defined functions */ + +/* Real time clock */ +#if !_FS_READONLY +DWORD get_fattime (void); /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */ + /* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */ +#endif + +/* Unicode - OEM code conversion */ +#if _USE_LFN +WCHAR ff_convert (WCHAR, UINT); +WCHAR ff_wtoupper (WCHAR); +#endif + +/* Sync functions */ +#if _FS_REENTRANT +BOOL ff_cre_syncobj(BYTE, _SYNC_t*); +BOOL ff_del_syncobj(_SYNC_t); +BOOL ff_req_grant(_SYNC_t); +void ff_rel_grant(_SYNC_t); +#endif + + + +/*--------------------------------------------------------------*/ +/* Flags and offset address */ + + +/* File access control and file status flags (FIL.flag) */ + +#define FA_READ 0x01 +#define FA_OPEN_EXISTING 0x00 +#if _FS_READONLY == 0 +#define FA_WRITE 0x02 +#define FA_CREATE_NEW 0x04 +#define FA_CREATE_ALWAYS 0x08 +#define FA_OPEN_ALWAYS 0x10 +#define FA__WRITTEN 0x20 +#define FA__DIRTY 0x40 +#endif +#define FA__ERROR 0x80 + + +/* FAT sub type (FATFS.fs_type) */ + +#define FS_FAT12 1 +#define FS_FAT16 2 +#define FS_FAT32 3 + + +/* File attribute bits for directory entry */ + +#define AM_RDO 0x01 /* Read only */ +#define AM_HID 0x02 /* Hidden */ +#define AM_SYS 0x04 /* System */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_DIR 0x10 /* Directory */ +#define AM_ARC 0x20 /* Archive */ +#define AM_MASK 0x3F /* Mask of defined bits */ + + +/* FatFs refers the members in the FAT structures with byte offset instead +/ of structure member because there are incompatibility of the packing option +/ between various compilers. */ + +#define BS_jmpBoot 0 +#define BS_OEMName 3 +#define BPB_BytsPerSec 11 +#define BPB_SecPerClus 13 +#define BPB_RsvdSecCnt 14 +#define BPB_NumFATs 16 +#define BPB_RootEntCnt 17 +#define BPB_TotSec16 19 +#define BPB_Media 21 +#define BPB_FATSz16 22 +#define BPB_SecPerTrk 24 +#define BPB_NumHeads 26 +#define BPB_HiddSec 28 +#define BPB_TotSec32 32 +#define BS_55AA 510 + +#define BS_DrvNum 36 +#define BS_BootSig 38 +#define BS_VolID 39 +#define BS_VolLab 43 +#define BS_FilSysType 54 + +#define BPB_FATSz32 36 +#define BPB_ExtFlags 40 +#define BPB_FSVer 42 +#define BPB_RootClus 44 +#define BPB_FSInfo 48 +#define BPB_BkBootSec 50 +#define BS_DrvNum32 64 +#define BS_BootSig32 66 +#define BS_VolID32 67 +#define BS_VolLab32 71 +#define BS_FilSysType32 82 + +#define FSI_LeadSig 0 +#define FSI_StrucSig 484 +#define FSI_Free_Count 488 +#define FSI_Nxt_Free 492 + +#define MBR_Table 446 + +#define DIR_Name 0 +#define DIR_Attr 11 +#define DIR_NTres 12 +#define DIR_CrtTime 14 +#define DIR_CrtDate 16 +#define DIR_FstClusHI 20 +#define DIR_WrtTime 22 +#define DIR_WrtDate 24 +#define DIR_FstClusLO 26 +#define DIR_FileSize 28 +#define LDIR_Ord 0 +#define LDIR_Attr 11 +#define LDIR_Type 12 +#define LDIR_Chksum 13 +#define LDIR_FstClusLO 26 + + + +/*--------------------------------*/ +/* Multi-byte word access macros */ + +#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val) +#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) +#else /* Use byte-by-byte access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8) +#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24) +#endif + + +#endif /* _FATFS */ diff --git a/Projects/TemperatureDataLogger/Lib/FATFs/ff.lst b/Projects/TemperatureDataLogger/Lib/FATFs/ff.lst new file mode 100644 index 000000000..74f818a13 --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/FATFs/ff.lst @@ -0,0 +1,6864 @@ + 1 .file "ff.c" + 2 __SREG__ = 0x3f + 3 __SP_H__ = 0x3e + 4 __SP_L__ = 0x3d + 5 __CCP__ = 0x34 + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 15 .Ltext0: + 16 .section .text.mem_cpy,"ax",@progbits + 18 mem_cpy: + 19 .LFB52: + 20 .LSM0: + 21 .LVL0: + 22 0000 CF93 push r28 + 23 0002 DF93 push r29 + 24 /* prologue: function */ + 25 /* frame size = 0 */ + 26 0004 EC01 movw r28,r24 + 27 .LSM1: + 28 0006 20E0 ldi r18,lo8(0) + 29 0008 30E0 ldi r19,hi8(0) + 30 000a 00C0 rjmp .L2 + 31 .LVL1: + 32 .L3: + 33 .LSM2: + 34 000c FE01 movw r30,r28 + 35 000e E20F add r30,r18 + 36 0010 F31F adc r31,r19 + 37 0012 DB01 movw r26,r22 + 38 0014 A20F add r26,r18 + 39 0016 B31F adc r27,r19 + 40 0018 8C91 ld r24,X + 41 001a 8083 st Z,r24 + 42 001c 2F5F subi r18,lo8(-(1)) + 43 001e 3F4F sbci r19,hi8(-(1)) + 44 .LVL2: + 45 .L2: + 46 0020 4150 subi r20,lo8(-(-1)) + 47 0022 5040 sbci r21,hi8(-(-1)) + 48 0024 8FEF ldi r24,hi8(-1) + 49 0026 4F3F cpi r20,lo8(-1) + 50 0028 5807 cpc r21,r24 + 51 002a 01F4 brne .L3 + 52 /* epilogue start */ + 53 .LSM3: + 54 002c DF91 pop r29 + 55 002e CF91 pop r28 + 56 .LVL3: + 57 0030 0895 ret + 58 .LFE52: + 60 .section .text.mem_set,"ax",@progbits + 62 mem_set: + 63 .LFB53: + 64 .LSM4: + 65 .LVL4: + 66 /* prologue: function */ + 67 /* frame size = 0 */ + 68 .LSM5: + 69 0000 FC01 movw r30,r24 + 70 .LVL5: + 71 0002 00C0 rjmp .L6 + 72 .LVL6: + 73 .L7: + 74 .LSM6: + 75 0004 6193 st Z+,r22 + 76 .LVL7: + 77 .L6: + 78 0006 4150 subi r20,lo8(-(-1)) + 79 0008 5040 sbci r21,hi8(-(-1)) + 80 000a 8FEF ldi r24,hi8(-1) + 81 000c 4F3F cpi r20,lo8(-1) + 82 000e 5807 cpc r21,r24 + 83 .LVL8: + 84 0010 01F4 brne .L7 + 85 /* epilogue start */ + 86 .LSM7: + 87 0012 0895 ret + 88 .LFE53: + 90 .section .text.clust2sect,"ax",@progbits + 91 .global clust2sect + 93 clust2sect: + 94 .LFB62: + 95 .LSM8: + 96 .LVL9: + 97 0000 EF92 push r14 + 98 0002 FF92 push r15 + 99 0004 0F93 push r16 + 100 0006 1F93 push r17 + 101 0008 CF93 push r28 + 102 000a DF93 push r29 + 103 /* prologue: function */ + 104 /* frame size = 0 */ + 105 000c EC01 movw r28,r24 + 106 000e 7A01 movw r14,r20 + 107 0010 8B01 movw r16,r22 + 108 .LSM9: + 109 0012 8EEF ldi r24,lo8(-2) + 110 0014 9FEF ldi r25,hi8(-2) + 111 0016 AFEF ldi r26,hlo8(-2) + 112 0018 BFEF ldi r27,hhi8(-2) + 113 .LVL10: + 114 001a E80E add r14,r24 + 115 001c F91E adc r15,r25 + 116 001e 0A1F adc r16,r26 + 117 0020 1B1F adc r17,r27 + 118 .LVL11: + 119 .LSM10: + 120 0022 8A8D ldd r24,Y+26 + 121 0024 9B8D ldd r25,Y+27 + 122 0026 AC8D ldd r26,Y+28 + 123 0028 BD8D ldd r27,Y+29 + 124 002a 0297 sbiw r24,2 + 125 002c A109 sbc r26,__zero_reg__ + 126 002e B109 sbc r27,__zero_reg__ + 127 0030 E816 cp r14,r24 + 128 0032 F906 cpc r15,r25 + 129 0034 0A07 cpc r16,r26 + 130 0036 1B07 cpc r17,r27 + 131 0038 00F0 brlo .L10 + 132 003a 20E0 ldi r18,lo8(0) + 133 003c 30E0 ldi r19,hi8(0) + 134 003e 40E0 ldi r20,hlo8(0) + 135 0040 50E0 ldi r21,hhi8(0) + 136 0042 00C0 rjmp .L11 + 137 .L10: + 138 .LSM11: + 139 0044 2A81 ldd r18,Y+2 + 140 0046 30E0 ldi r19,lo8(0) + 141 0048 40E0 ldi r20,lo8(0) + 142 004a 50E0 ldi r21,hi8(0) + 143 004c C801 movw r24,r16 + 144 004e B701 movw r22,r14 + 145 0050 0E94 0000 call __mulsi3 + 146 0054 9B01 movw r18,r22 + 147 0056 AC01 movw r20,r24 + 148 0058 8EA1 ldd r24,Y+38 + 149 005a 9FA1 ldd r25,Y+39 + 150 005c A8A5 ldd r26,Y+40 + 151 005e B9A5 ldd r27,Y+41 + 152 0060 280F add r18,r24 + 153 0062 391F adc r19,r25 + 154 0064 4A1F adc r20,r26 + 155 0066 5B1F adc r21,r27 + 156 .L11: + 157 .LSM12: + 158 0068 B901 movw r22,r18 + 159 006a CA01 movw r24,r20 + 160 /* epilogue start */ + 161 006c DF91 pop r29 + 162 006e CF91 pop r28 + 163 .LVL12: + 164 0070 1F91 pop r17 + 165 0072 0F91 pop r16 + 166 0074 FF90 pop r15 + 167 0076 EF90 pop r14 + 168 .LVL13: + 169 0078 0895 ret + 170 .LFE62: + 172 .section .text.f_mount,"ax",@progbits + 173 .global f_mount + 175 f_mount: + 176 .LFB72: + 177 .LSM13: + 178 .LVL14: + 179 /* prologue: function */ + 180 /* frame size = 0 */ + 181 0000 DB01 movw r26,r22 + 182 .LSM14: + 183 0002 8823 tst r24 + 184 0004 01F0 breq .L14 + 185 .LVL15: + 186 0006 8BE0 ldi r24,lo8(11) + 187 .LVL16: + 188 0008 0895 ret + 189 .LVL17: + 190 .L14: + 191 .LSM15: + 192 000a E091 0000 lds r30,FatFs + 193 000e F091 0000 lds r31,(FatFs)+1 + 194 .LVL18: + 195 .LSM16: + 196 0012 3097 sbiw r30,0 + 197 0014 01F0 breq .L16 + 198 .LSM17: + 199 0016 1082 st Z,__zero_reg__ + 200 .L16: + 201 .LSM18: + 202 0018 1097 sbiw r26,0 + 203 001a 01F0 breq .L17 + 204 .LSM19: + 205 001c 1C92 st X,__zero_reg__ + 206 .L17: + 207 .LSM20: + 208 001e B093 0000 sts (FatFs)+1,r27 + 209 0022 A093 0000 sts FatFs,r26 + 210 0026 80E0 ldi r24,lo8(0) + 211 .LVL19: + 212 .LSM21: + 213 0028 0895 ret + 214 .LFE72: + 216 .section .text.validate,"ax",@progbits + 218 validate: + 219 .LFB71: + 220 .LSM22: + 221 .LVL20: + 222 /* prologue: function */ + 223 /* frame size = 0 */ + 224 0000 FC01 movw r30,r24 + 225 .LSM23: + 226 0002 0097 sbiw r24,0 + 227 0004 01F0 breq .L20 + 228 0006 8081 ld r24,Z + 229 .LVL21: + 230 0008 8823 tst r24 + 231 000a 01F0 breq .L20 + 232 000c 8681 ldd r24,Z+6 + 233 000e 9781 ldd r25,Z+7 + 234 0010 8617 cp r24,r22 + 235 0012 9707 cpc r25,r23 + 236 0014 01F4 brne .L20 + 237 .LSM24: + 238 0016 8181 ldd r24,Z+1 + 239 0018 0E94 0000 call disk_status + 240 .LVL22: + 241 001c 80FD sbrc r24,0 + 242 001e 00C0 rjmp .L21 + 243 0020 80E0 ldi r24,lo8(0) + 244 0022 0895 ret + 245 .L21: + 246 0024 83E0 ldi r24,lo8(3) + 247 0026 0895 ret + 248 .LVL23: + 249 .L20: + 250 0028 89E0 ldi r24,lo8(9) + 251 .LSM25: + 252 002a 0895 ret + 253 .LFE71: + 255 .section .text.move_window,"ax",@progbits + 257 move_window: + 258 .LFB56: + 259 .LSM26: + 260 .LVL24: + 261 0000 6F92 push r6 + 262 0002 7F92 push r7 + 263 0004 8F92 push r8 + 264 0006 9F92 push r9 + 265 0008 AF92 push r10 + 266 000a BF92 push r11 + 267 000c CF92 push r12 + 268 000e DF92 push r13 + 269 0010 EF92 push r14 + 270 0012 FF92 push r15 + 271 0014 0F93 push r16 + 272 0016 1F93 push r17 + 273 0018 CF93 push r28 + 274 001a DF93 push r29 + 275 /* prologue: function */ + 276 /* frame size = 0 */ + 277 001c EC01 movw r28,r24 + 278 001e 4A01 movw r8,r20 + 279 0020 5B01 movw r10,r22 + 280 .LSM27: + 281 0022 CAA4 ldd r12,Y+42 + 282 0024 DBA4 ldd r13,Y+43 + 283 0026 ECA4 ldd r14,Y+44 + 284 0028 FDA4 ldd r15,Y+45 + 285 .LVL25: + 286 .LSM28: + 287 002a C416 cp r12,r20 + 288 002c D506 cpc r13,r21 + 289 002e E606 cpc r14,r22 + 290 0030 F706 cpc r15,r23 + 291 0032 01F4 brne .+2 + 292 0034 00C0 rjmp .L25 + 293 .LVL26: + 294 .LSM29: + 295 0036 8C81 ldd r24,Y+4 + 296 0038 8823 tst r24 + 297 003a 01F0 breq .L26 + 298 .LSM30: + 299 003c 8EE2 ldi r24,lo8(46) + 300 003e 682E mov r6,r24 + 301 0040 712C mov r7,__zero_reg__ + 302 0042 6C0E add r6,r28 + 303 0044 7D1E adc r7,r29 + 304 0046 8981 ldd r24,Y+1 + 305 0048 B301 movw r22,r6 + 306 004a A701 movw r20,r14 + 307 004c 9601 movw r18,r12 + 308 004e 01E0 ldi r16,lo8(1) + 309 0050 0E94 0000 call disk_write + 310 .LVL27: + 311 0054 8823 tst r24 + 312 0056 01F4 brne .L27 + 313 .LSM31: + 314 0058 1C82 std Y+4,__zero_reg__ + 315 .LSM32: + 316 005a 8E89 ldd r24,Y+22 + 317 005c 9F89 ldd r25,Y+23 + 318 005e A88D ldd r26,Y+24 + 319 0060 B98D ldd r27,Y+25 + 320 0062 2E8D ldd r18,Y+30 + 321 0064 3F8D ldd r19,Y+31 + 322 0066 48A1 ldd r20,Y+32 + 323 0068 59A1 ldd r21,Y+33 + 324 006a 820F add r24,r18 + 325 006c 931F adc r25,r19 + 326 006e A41F adc r26,r20 + 327 0070 B51F adc r27,r21 + 328 0072 C816 cp r12,r24 + 329 0074 D906 cpc r13,r25 + 330 0076 EA06 cpc r14,r26 + 331 0078 FB06 cpc r15,r27 + 332 007a 00F4 brsh .L26 + 333 .LBB2: + 334 .LSM33: + 335 007c 1B81 ldd r17,Y+3 + 336 .LVL28: + 337 007e 00C0 rjmp .L28 + 338 .L29: + 339 .LSM34: + 340 0080 8E89 ldd r24,Y+22 + 341 0082 9F89 ldd r25,Y+23 + 342 0084 A88D ldd r26,Y+24 + 343 0086 B98D ldd r27,Y+25 + 344 0088 C80E add r12,r24 + 345 008a D91E adc r13,r25 + 346 008c EA1E adc r14,r26 + 347 008e FB1E adc r15,r27 + 348 .LSM35: + 349 0090 8981 ldd r24,Y+1 + 350 0092 B301 movw r22,r6 + 351 0094 A701 movw r20,r14 + 352 0096 9601 movw r18,r12 + 353 0098 01E0 ldi r16,lo8(1) + 354 009a 0E94 0000 call disk_write + 355 .LSM36: + 356 009e 1150 subi r17,lo8(-(-1)) + 357 .L28: + 358 00a0 1230 cpi r17,lo8(2) + 359 00a2 00F4 brsh .L29 + 360 .LVL29: + 361 .L26: + 362 .LBE2: + 363 .LSM37: + 364 00a4 8114 cp r8,__zero_reg__ + 365 00a6 9104 cpc r9,__zero_reg__ + 366 00a8 A104 cpc r10,__zero_reg__ + 367 00aa B104 cpc r11,__zero_reg__ + 368 00ac 01F0 breq .L25 + 369 .LSM38: + 370 00ae BE01 movw r22,r28 + 371 00b0 625D subi r22,lo8(-(46)) + 372 00b2 7F4F sbci r23,hi8(-(46)) + 373 00b4 8981 ldd r24,Y+1 + 374 00b6 A501 movw r20,r10 + 375 00b8 9401 movw r18,r8 + 376 00ba 01E0 ldi r16,lo8(1) + 377 00bc 0E94 0000 call disk_read + 378 00c0 8823 tst r24 + 379 00c2 01F4 brne .L27 + 380 .LSM39: + 381 00c4 8AA6 std Y+42,r8 + 382 00c6 9BA6 std Y+43,r9 + 383 00c8 ACA6 std Y+44,r10 + 384 00ca BDA6 std Y+45,r11 + 385 00cc 00C0 rjmp .L30 + 386 .L27: + 387 00ce 81E0 ldi r24,lo8(1) + 388 00d0 00C0 rjmp .L30 + 389 .LVL30: + 390 .L25: + 391 00d2 80E0 ldi r24,lo8(0) + 392 .LVL31: + 393 .L30: + 394 /* epilogue start */ + 395 .LSM40: + 396 00d4 DF91 pop r29 + 397 00d6 CF91 pop r28 + 398 .LVL32: + 399 00d8 1F91 pop r17 + 400 .LVL33: + 401 00da 0F91 pop r16 + 402 00dc FF90 pop r15 + 403 00de EF90 pop r14 + 404 00e0 DF90 pop r13 + 405 00e2 CF90 pop r12 + 406 .LVL34: + 407 00e4 BF90 pop r11 + 408 00e6 AF90 pop r10 + 409 00e8 9F90 pop r9 + 410 00ea 8F90 pop r8 + 411 .LVL35: + 412 00ec 7F90 pop r7 + 413 00ee 6F90 pop r6 + 414 00f0 0895 ret + 415 .LFE56: + 417 .section .text.put_fat,"ax",@progbits + 418 .global put_fat + 420 put_fat: + 421 .LFB59: + 422 .LSM41: + 423 .LVL36: + 424 0000 2F92 push r2 + 425 0002 3F92 push r3 + 426 0004 4F92 push r4 + 427 0006 5F92 push r5 + 428 0008 6F92 push r6 + 429 000a 7F92 push r7 + 430 000c 8F92 push r8 + 431 000e 9F92 push r9 + 432 0010 AF92 push r10 + 433 0012 BF92 push r11 + 434 0014 CF92 push r12 + 435 0016 DF92 push r13 + 436 0018 EF92 push r14 + 437 001a FF92 push r15 + 438 001c 0F93 push r16 + 439 .LVL37: + 440 001e 1F93 push r17 + 441 0020 CF93 push r28 + 442 0022 DF93 push r29 + 443 /* prologue: function */ + 444 /* frame size = 0 */ + 445 0024 3C01 movw r6,r24 + 446 0026 6A01 movw r12,r20 + 447 0028 7B01 movw r14,r22 + 448 002a 4801 movw r8,r16 + 449 002c 5901 movw r10,r18 + 450 .LVL38: + 451 .LSM42: + 452 002e 4230 cpi r20,lo8(2) + 453 0030 5105 cpc r21,__zero_reg__ + 454 0032 6105 cpc r22,__zero_reg__ + 455 0034 7105 cpc r23,__zero_reg__ + 456 .LVL39: + 457 0036 00F4 brsh .+2 + 458 0038 00C0 rjmp .L33 + 459 .LVL40: + 460 003a F301 movw r30,r6 + 461 003c 828D ldd r24,Z+26 + 462 003e 938D ldd r25,Z+27 + 463 0040 A48D ldd r26,Z+28 + 464 0042 B58D ldd r27,Z+29 + 465 0044 4817 cp r20,r24 + 466 0046 5907 cpc r21,r25 + 467 0048 6A07 cpc r22,r26 + 468 004a 7B07 cpc r23,r27 + 469 004c 00F0 brlo .+2 + 470 004e 00C0 rjmp .L33 + 471 .LSM43: + 472 0050 268C ldd r2,Z+30 + 473 0052 378C ldd r3,Z+31 + 474 0054 40A0 ldd r4,Z+32 + 475 0056 51A0 ldd r5,Z+33 + 476 .LVL41: + 477 .LSM44: + 478 0058 8081 ld r24,Z + 479 005a 8230 cpi r24,lo8(2) + 480 005c 01F4 brne .+2 + 481 005e 00C0 rjmp .L36 + 482 0060 8330 cpi r24,lo8(3) + 483 0062 01F4 brne .+2 + 484 0064 00C0 rjmp .L37 + 485 0066 8130 cpi r24,lo8(1) + 486 0068 01F0 breq .L35 + 487 006a 22E0 ldi r18,lo8(2) + 488 .LVL42: + 489 006c 00C0 rjmp .L38 + 490 .LVL43: + 491 .L35: + 492 .LSM45: + 493 006e EA01 movw r28,r20 + 494 .LVL44: + 495 0070 D695 lsr r29 + 496 0072 C795 ror r28 + 497 .LVL45: + 498 0074 C40F add r28,r20 + 499 0076 D51F adc r29,r21 + 500 .LSM46: + 501 0078 AE01 movw r20,r28 + 502 .LVL46: + 503 007a 452F mov r20,r21 + 504 007c 5527 clr r21 + 505 007e 4695 lsr r20 + 506 0080 60E0 ldi r22,lo8(0) + 507 0082 70E0 ldi r23,hi8(0) + 508 0084 420D add r20,r2 + 509 0086 531D adc r21,r3 + 510 0088 641D adc r22,r4 + 511 008a 751D adc r23,r5 + 512 008c C301 movw r24,r6 + 513 008e 0E94 0000 call move_window + 514 0092 282F mov r18,r24 + 515 .LVL47: + 516 .LSM47: + 517 0094 8823 tst r24 + 518 0096 01F0 breq .+2 + 519 0098 00C0 rjmp .L38 + 520 .LVL48: + 521 .LSM48: + 522 009a DE01 movw r26,r28 + 523 009c B170 andi r27,hi8(511) + 524 .LSM49: + 525 009e 8601 movw r16,r12 + 526 .LVL49: + 527 00a0 0170 andi r16,lo8(1) + 528 00a2 1070 andi r17,hi8(1) + 529 00a4 0115 cp r16,__zero_reg__ + 530 00a6 1105 cpc r17,__zero_reg__ + 531 00a8 01F0 breq .L39 + 532 00aa F301 movw r30,r6 + 533 00ac EA0F add r30,r26 + 534 00ae FB1F adc r31,r27 + 535 00b0 86A5 ldd r24,Z+46 + 536 .LVL50: + 537 00b2 8F70 andi r24,lo8(15) + 538 00b4 982D mov r25,r8 + 539 .LVL51: + 540 00b6 9295 swap r25 + 541 00b8 907F andi r25,lo8(-16) + 542 00ba 982B or r25,r24 + 543 00bc 00C0 rjmp .L40 + 544 .LVL52: + 545 .L39: + 546 00be 982D mov r25,r8 + 547 .LVL53: + 548 .L40: + 549 00c0 A60D add r26,r6 + 550 00c2 B71D adc r27,r7 + 551 00c4 9E96 adiw r26,46 + 552 00c6 9C93 st X,r25 + 553 .LSM50: + 554 00c8 2196 adiw r28,1 + 555 .LVL54: + 556 .LSM51: + 557 00ca 81E0 ldi r24,lo8(1) + 558 00cc F301 movw r30,r6 + 559 00ce 8483 std Z+4,r24 + 560 .LSM52: + 561 00d0 AE01 movw r20,r28 + 562 00d2 452F mov r20,r21 + 563 00d4 5527 clr r21 + 564 00d6 4695 lsr r20 + 565 00d8 60E0 ldi r22,lo8(0) + 566 00da 70E0 ldi r23,hi8(0) + 567 00dc 420D add r20,r2 + 568 00de 531D adc r21,r3 + 569 00e0 641D adc r22,r4 + 570 00e2 751D adc r23,r5 + 571 00e4 C301 movw r24,r6 + 572 00e6 0E94 0000 call move_window + 573 .LVL55: + 574 00ea 282F mov r18,r24 + 575 .LVL56: + 576 .LSM53: + 577 00ec 8823 tst r24 + 578 00ee 01F0 breq .+2 + 579 00f0 00C0 rjmp .L38 + 580 .LVL57: + 581 .LSM54: + 582 00f2 D170 andi r29,hi8(511) + 583 .LVL58: + 584 .LSM55: + 585 00f4 012B or r16,r17 + 586 00f6 01F0 breq .L41 + 587 00f8 84E0 ldi r24,4 + 588 00fa B694 1: lsr r11 + 589 00fc A794 ror r10 + 590 00fe 9794 ror r9 + 591 0100 8794 ror r8 + 592 0102 8A95 dec r24 + 593 0104 01F4 brne 1b + 594 .LVL59: + 595 0106 482D mov r20,r8 + 596 0108 00C0 rjmp .L42 + 597 .LVL60: + 598 .L41: + 599 010a F301 movw r30,r6 + 600 010c EC0F add r30,r28 + 601 010e FD1F adc r31,r29 + 602 0110 46A5 ldd r20,Z+46 + 603 0112 407F andi r20,lo8(-16) + 604 0114 BB27 clr r27 + 605 0116 AB2D mov r26,r11 + 606 0118 9A2D mov r25,r10 + 607 011a 892D mov r24,r9 + 608 .LVL61: + 609 011c 8F70 andi r24,lo8(15) + 610 011e 482B or r20,r24 + 611 .L42: + 612 0120 C60D add r28,r6 + 613 0122 D71D adc r29,r7 + 614 0124 4EA7 std Y+46,r20 + 615 0126 00C0 rjmp .L38 + 616 .LVL62: + 617 .L36: + 618 .LSM56: + 619 0128 452F mov r20,r21 + 620 012a 562F mov r21,r22 + 621 012c 672F mov r22,r23 + 622 012e 7727 clr r23 + 623 .LVL63: + 624 0130 420D add r20,r2 + 625 0132 531D adc r21,r3 + 626 0134 641D adc r22,r4 + 627 0136 751D adc r23,r5 + 628 0138 C301 movw r24,r6 + 629 013a 0E94 0000 call move_window + 630 013e 282F mov r18,r24 + 631 .LVL64: + 632 .LSM57: + 633 0140 8823 tst r24 + 634 0142 01F4 brne .L38 + 635 .LVL65: + 636 .LSM58: + 637 0144 F601 movw r30,r12 + 638 .LVL66: + 639 0146 EE0F lsl r30 + 640 0148 FF1F rol r31 + 641 014a F170 andi r31,hi8(511) + 642 014c E60D add r30,r6 + 643 014e F71D adc r31,r7 + 644 0150 86A6 std Z+46,r8 + 645 0152 892D mov r24,r9 + 646 0154 9927 clr r25 + 647 .LVL67: + 648 0156 87A7 std Z+47,r24 + 649 0158 00C0 rjmp .L38 + 650 .LVL68: + 651 .L37: + 652 .LSM59: + 653 015a E7E0 ldi r30,7 + 654 015c 7695 1: lsr r23 + 655 015e 6795 ror r22 + 656 0160 5795 ror r21 + 657 0162 4795 ror r20 + 658 0164 EA95 dec r30 + 659 0166 01F4 brne 1b + 660 .LVL69: + 661 0168 420D add r20,r2 + 662 016a 531D adc r21,r3 + 663 016c 641D adc r22,r4 + 664 016e 751D adc r23,r5 + 665 0170 C301 movw r24,r6 + 666 0172 0E94 0000 call move_window + 667 0176 282F mov r18,r24 + 668 .LVL70: + 669 .LSM60: + 670 0178 8823 tst r24 + 671 017a 01F4 brne .L38 + 672 .LVL71: + 673 .LSM61: + 674 017c F601 movw r30,r12 + 675 .LVL72: + 676 017e EE0F lsl r30 + 677 0180 FF1F rol r31 + 678 0182 EE0F lsl r30 + 679 0184 FF1F rol r31 + 680 0186 F170 andi r31,hi8(511) + 681 0188 E60D add r30,r6 + 682 018a F71D adc r31,r7 + 683 018c 86A6 std Z+46,r8 + 684 018e 892D mov r24,r9 + 685 0190 9927 clr r25 + 686 .LVL73: + 687 0192 87A7 std Z+47,r24 + 688 0194 C501 movw r24,r10 + 689 0196 AA27 clr r26 + 690 0198 BB27 clr r27 + 691 019a 80AB std Z+48,r24 + 692 019c 8B2D mov r24,r11 + 693 019e 9927 clr r25 + 694 01a0 AA27 clr r26 + 695 01a2 BB27 clr r27 + 696 01a4 81AB std Z+49,r24 + 697 .LVL74: + 698 .L38: + 699 .LSM62: + 700 01a6 81E0 ldi r24,lo8(1) + 701 01a8 F301 movw r30,r6 + 702 01aa 8483 std Z+4,r24 + 703 01ac 00C0 rjmp .L43 + 704 .LVL75: + 705 .L33: + 706 01ae 22E0 ldi r18,lo8(2) + 707 .LVL76: + 708 .L43: + 709 .LSM63: + 710 01b0 822F mov r24,r18 + 711 /* epilogue start */ + 712 01b2 DF91 pop r29 + 713 01b4 CF91 pop r28 + 714 .LVL77: + 715 01b6 1F91 pop r17 + 716 01b8 0F91 pop r16 + 717 01ba FF90 pop r15 + 718 01bc EF90 pop r14 + 719 01be DF90 pop r13 + 720 01c0 CF90 pop r12 + 721 01c2 BF90 pop r11 + 722 01c4 AF90 pop r10 + 723 01c6 9F90 pop r9 + 724 01c8 8F90 pop r8 + 725 .LVL78: + 726 01ca 7F90 pop r7 + 727 01cc 6F90 pop r6 + 728 .LVL79: + 729 01ce 5F90 pop r5 + 730 01d0 4F90 pop r4 + 731 01d2 3F90 pop r3 + 732 01d4 2F90 pop r2 + 733 .LVL80: + 734 01d6 0895 ret + 735 .LFE59: + 737 .section .text.get_fat,"ax",@progbits + 738 .global get_fat + 740 get_fat: + 741 .LFB58: + 742 .LSM64: + 743 .LVL81: + 744 0000 7F92 push r7 + 745 0002 8F92 push r8 + 746 0004 9F92 push r9 + 747 0006 AF92 push r10 + 748 0008 BF92 push r11 + 749 000a CF92 push r12 + 750 000c DF92 push r13 + 751 000e EF92 push r14 + 752 0010 FF92 push r15 + 753 0012 0F93 push r16 + 754 0014 1F93 push r17 + 755 0016 CF93 push r28 + 756 0018 DF93 push r29 + 757 /* prologue: function */ + 758 /* frame size = 0 */ + 759 001a 4C01 movw r8,r24 + 760 001c 7A01 movw r14,r20 + 761 001e 8B01 movw r16,r22 + 762 .LSM65: + 763 0020 4230 cpi r20,lo8(2) + 764 0022 5105 cpc r21,__zero_reg__ + 765 0024 6105 cpc r22,__zero_reg__ + 766 0026 7105 cpc r23,__zero_reg__ + 767 .LVL82: + 768 0028 00F4 brsh .+2 + 769 002a 00C0 rjmp .L46 + 770 002c F401 movw r30,r8 + 771 002e 828D ldd r24,Z+26 + 772 0030 938D ldd r25,Z+27 + 773 0032 A48D ldd r26,Z+28 + 774 0034 B58D ldd r27,Z+29 + 775 0036 4817 cp r20,r24 + 776 0038 5907 cpc r21,r25 + 777 003a 6A07 cpc r22,r26 + 778 003c 7B07 cpc r23,r27 + 779 003e 00F0 brlo .+2 + 780 0040 00C0 rjmp .L46 + 781 .LSM66: + 782 0042 A68C ldd r10,Z+30 + 783 0044 B78C ldd r11,Z+31 + 784 0046 C0A0 ldd r12,Z+32 + 785 0048 D1A0 ldd r13,Z+33 + 786 .LVL83: + 787 .LSM67: + 788 004a 8081 ld r24,Z + 789 004c 8230 cpi r24,lo8(2) + 790 004e 01F4 brne .+2 + 791 0050 00C0 rjmp .L49 + 792 0052 8330 cpi r24,lo8(3) + 793 0054 01F4 brne .+2 + 794 0056 00C0 rjmp .L50 + 795 0058 8130 cpi r24,lo8(1) + 796 005a 01F0 breq .+2 + 797 005c 00C0 rjmp .L47 + 798 .LSM68: + 799 005e EA01 movw r28,r20 + 800 .LVL84: + 801 0060 D695 lsr r29 + 802 0062 C795 ror r28 + 803 .LVL85: + 804 0064 CE0D add r28,r14 + 805 0066 DF1D adc r29,r15 + 806 .LSM69: + 807 0068 AE01 movw r20,r28 + 808 006a 452F mov r20,r21 + 809 006c 5527 clr r21 + 810 006e 4695 lsr r20 + 811 0070 60E0 ldi r22,lo8(0) + 812 0072 70E0 ldi r23,hi8(0) + 813 0074 4A0D add r20,r10 + 814 0076 5B1D adc r21,r11 + 815 0078 6C1D adc r22,r12 + 816 007a 7D1D adc r23,r13 + 817 007c C401 movw r24,r8 + 818 007e 0E94 0000 call move_window + 819 0082 8823 tst r24 + 820 0084 01F0 breq .+2 + 821 0086 00C0 rjmp .L47 + 822 .LSM70: + 823 0088 FE01 movw r30,r28 + 824 008a F170 andi r31,hi8(511) + 825 008c E80D add r30,r8 + 826 008e F91D adc r31,r9 + 827 0090 76A4 ldd r7,Z+46 + 828 0092 2196 adiw r28,1 + 829 .LVL86: + 830 .LSM71: + 831 0094 AE01 movw r20,r28 + 832 0096 452F mov r20,r21 + 833 0098 5527 clr r21 + 834 009a 4695 lsr r20 + 835 009c 60E0 ldi r22,lo8(0) + 836 009e 70E0 ldi r23,hi8(0) + 837 00a0 4A0D add r20,r10 + 838 00a2 5B1D adc r21,r11 + 839 00a4 6C1D adc r22,r12 + 840 00a6 7D1D adc r23,r13 + 841 00a8 C401 movw r24,r8 + 842 00aa 0E94 0000 call move_window + 843 00ae 8823 tst r24 + 844 00b0 01F0 breq .+2 + 845 00b2 00C0 rjmp .L47 + 846 .LSM72: + 847 00b4 672D mov r22,r7 + 848 .LVL87: + 849 00b6 70E0 ldi r23,lo8(0) + 850 .LVL88: + 851 .LSM73: + 852 00b8 D170 andi r29,hi8(511) + 853 00ba C80D add r28,r8 + 854 00bc D91D adc r29,r9 + 855 00be 9EA5 ldd r25,Y+46 + 856 00c0 80E0 ldi r24,lo8(0) + 857 00c2 682B or r22,r24 + 858 00c4 792B or r23,r25 + 859 .LVL89: + 860 .LSM74: + 861 00c6 C701 movw r24,r14 + 862 .LVL90: + 863 00c8 8170 andi r24,lo8(1) + 864 00ca 9070 andi r25,hi8(1) + 865 00cc 892B or r24,r25 + 866 00ce 01F0 breq .L51 + 867 00d0 94E0 ldi r25,4 + 868 00d2 7695 1: lsr r23 + 869 00d4 6795 ror r22 + 870 00d6 9A95 dec r25 + 871 00d8 01F4 brne 1b + 872 00da 9B01 movw r18,r22 + 873 00dc 00C0 rjmp .L54 + 874 .L51: + 875 00de 9B01 movw r18,r22 + 876 00e0 40E0 ldi r20,lo8(0) + 877 00e2 50E0 ldi r21,hi8(0) + 878 00e4 3F70 andi r19,hi8(4095) + 879 00e6 4070 andi r20,hlo8(4095) + 880 00e8 5070 andi r21,hhi8(4095) + 881 00ea 00C0 rjmp .L52 + 882 .LVL91: + 883 .L49: + 884 .LSM75: + 885 00ec 452F mov r20,r21 + 886 00ee 562F mov r21,r22 + 887 00f0 672F mov r22,r23 + 888 00f2 7727 clr r23 + 889 .LVL92: + 890 00f4 4A0D add r20,r10 + 891 00f6 5B1D adc r21,r11 + 892 00f8 6C1D adc r22,r12 + 893 00fa 7D1D adc r23,r13 + 894 00fc C401 movw r24,r8 + 895 00fe 0E94 0000 call move_window + 896 0102 8823 tst r24 + 897 0104 01F0 breq .+2 + 898 0106 00C0 rjmp .L47 + 899 .LSM76: + 900 0108 F701 movw r30,r14 + 901 .LVL93: + 902 010a EE0F lsl r30 + 903 010c FF1F rol r31 + 904 010e F170 andi r31,hi8(511) + 905 0110 E80D add r30,r8 + 906 0112 F91D adc r31,r9 + 907 0114 97A5 ldd r25,Z+47 + 908 0116 80E0 ldi r24,lo8(0) + 909 0118 26A5 ldd r18,Z+46 + 910 011a 30E0 ldi r19,lo8(0) + 911 011c 822B or r24,r18 + 912 011e 932B or r25,r19 + 913 0120 9C01 movw r18,r24 + 914 .LVL94: + 915 .L54: + 916 0122 40E0 ldi r20,lo8(0) + 917 0124 50E0 ldi r21,hi8(0) + 918 0126 00C0 rjmp .L52 + 919 .LVL95: + 920 .L50: + 921 .LSM77: + 922 0128 B7E0 ldi r27,7 + 923 012a 7695 1: lsr r23 + 924 012c 6795 ror r22 + 925 012e 5795 ror r21 + 926 0130 4795 ror r20 + 927 0132 BA95 dec r27 + 928 0134 01F4 brne 1b + 929 .LVL96: + 930 0136 4A0D add r20,r10 + 931 0138 5B1D adc r21,r11 + 932 013a 6C1D adc r22,r12 + 933 013c 7D1D adc r23,r13 + 934 013e C401 movw r24,r8 + 935 0140 0E94 0000 call move_window + 936 0144 8823 tst r24 + 937 0146 01F4 brne .L47 + 938 .LSM78: + 939 0148 F701 movw r30,r14 + 940 .LVL97: + 941 014a EE0F lsl r30 + 942 014c FF1F rol r31 + 943 014e EE0F lsl r30 + 944 0150 FF1F rol r31 + 945 0152 F170 andi r31,hi8(511) + 946 0154 E80D add r30,r8 + 947 0156 F91D adc r31,r9 + 948 0158 81A9 ldd r24,Z+49 + 949 015a 90E0 ldi r25,lo8(0) + 950 015c A0E0 ldi r26,lo8(0) + 951 015e B0E0 ldi r27,hi8(0) + 952 0160 582F mov r21,r24 + 953 0162 4427 clr r20 + 954 0164 3327 clr r19 + 955 0166 2227 clr r18 + 956 0168 80A9 ldd r24,Z+48 + 957 016a 90E0 ldi r25,lo8(0) + 958 016c A0E0 ldi r26,lo8(0) + 959 016e B0E0 ldi r27,hi8(0) + 960 0170 DC01 movw r26,r24 + 961 0172 9927 clr r25 + 962 0174 8827 clr r24 + 963 0176 282B or r18,r24 + 964 0178 392B or r19,r25 + 965 017a 4A2B or r20,r26 + 966 017c 5B2B or r21,r27 + 967 017e 86A5 ldd r24,Z+46 + 968 0180 90E0 ldi r25,lo8(0) + 969 0182 A0E0 ldi r26,lo8(0) + 970 0184 B0E0 ldi r27,hi8(0) + 971 0186 282B or r18,r24 + 972 0188 392B or r19,r25 + 973 018a 4A2B or r20,r26 + 974 018c 5B2B or r21,r27 + 975 018e 97A5 ldd r25,Z+47 + 976 0190 80E0 ldi r24,lo8(0) + 977 0192 A0E0 ldi r26,lo8(0) + 978 0194 B0E0 ldi r27,hi8(0) + 979 0196 282B or r18,r24 + 980 0198 392B or r19,r25 + 981 019a 4A2B or r20,r26 + 982 019c 5B2B or r21,r27 + 983 019e 5F70 andi r21,hhi8(268435455) + 984 01a0 00C0 rjmp .L52 + 985 .LVL98: + 986 .L46: + 987 01a2 21E0 ldi r18,lo8(1) + 988 01a4 30E0 ldi r19,hi8(1) + 989 01a6 40E0 ldi r20,hlo8(1) + 990 01a8 50E0 ldi r21,hhi8(1) + 991 01aa 00C0 rjmp .L52 + 992 .LVL99: + 993 .L47: + 994 01ac 2FEF ldi r18,lo8(-1) + 995 01ae 3FEF ldi r19,hi8(-1) + 996 01b0 4FEF ldi r20,hlo8(-1) + 997 01b2 5FEF ldi r21,hhi8(-1) + 998 .LVL100: + 999 .L52: + 1000 .LSM79: + 1001 01b4 B901 movw r22,r18 + 1002 .LVL101: + 1003 01b6 CA01 movw r24,r20 + 1004 /* epilogue start */ + 1005 01b8 DF91 pop r29 + 1006 01ba CF91 pop r28 + 1007 .LVL102: + 1008 01bc 1F91 pop r17 + 1009 01be 0F91 pop r16 + 1010 01c0 FF90 pop r15 + 1011 01c2 EF90 pop r14 + 1012 .LVL103: + 1013 01c4 DF90 pop r13 + 1014 01c6 CF90 pop r12 + 1015 01c8 BF90 pop r11 + 1016 01ca AF90 pop r10 + 1017 .LVL104: + 1018 01cc 9F90 pop r9 + 1019 01ce 8F90 pop r8 + 1020 .LVL105: + 1021 01d0 7F90 pop r7 + 1022 01d2 0895 ret + 1023 .LFE58: + 1025 .section .text.create_chain,"ax",@progbits + 1027 create_chain: + 1028 .LFB61: + 1029 .LSM80: + 1030 .LVL106: + 1031 0000 2F92 push r2 + 1032 0002 3F92 push r3 + 1033 0004 4F92 push r4 + 1034 0006 5F92 push r5 + 1035 0008 6F92 push r6 + 1036 000a 7F92 push r7 + 1037 000c 8F92 push r8 + 1038 000e 9F92 push r9 + 1039 0010 AF92 push r10 + 1040 0012 BF92 push r11 + 1041 0014 CF92 push r12 + 1042 0016 DF92 push r13 + 1043 0018 EF92 push r14 + 1044 001a FF92 push r15 + 1045 001c 0F93 push r16 + 1046 001e 1F93 push r17 + 1047 0020 DF93 push r29 + 1048 0022 CF93 push r28 + 1049 0024 00D0 rcall . + 1050 0026 00D0 rcall . + 1051 0028 CDB7 in r28,__SP_L__ + 1052 002a DEB7 in r29,__SP_H__ + 1053 /* prologue: function */ + 1054 /* frame size = 4 */ + 1055 002c 1C01 movw r2,r24 + 1056 002e 2A01 movw r4,r20 + 1057 0030 3B01 movw r6,r22 + 1058 .LSM81: + 1059 0032 DC01 movw r26,r24 + 1060 0034 5A96 adiw r26,26 + 1061 0036 8D91 ld r24,X+ + 1062 0038 9D91 ld r25,X+ + 1063 003a 0D90 ld __tmp_reg__,X+ + 1064 003c BC91 ld r27,X + 1065 003e A02D mov r26,__tmp_reg__ + 1066 .LVL107: + 1067 0040 8983 std Y+1,r24 + 1068 0042 9A83 std Y+2,r25 + 1069 0044 AB83 std Y+3,r26 + 1070 0046 BC83 std Y+4,r27 + 1071 .LVL108: + 1072 .LSM82: + 1073 0048 4115 cp r20,__zero_reg__ + 1074 004a 5105 cpc r21,__zero_reg__ + 1075 004c 6105 cpc r22,__zero_reg__ + 1076 004e 7105 cpc r23,__zero_reg__ + 1077 0050 01F4 brne .L56 + 1078 .LSM83: + 1079 0052 F101 movw r30,r2 + 1080 0054 8284 ldd r8,Z+10 + 1081 0056 9384 ldd r9,Z+11 + 1082 0058 A484 ldd r10,Z+12 + 1083 005a B584 ldd r11,Z+13 + 1084 .LVL109: + 1085 .LSM84: + 1086 005c 8114 cp r8,__zero_reg__ + 1087 005e 9104 cpc r9,__zero_reg__ + 1088 0060 A104 cpc r10,__zero_reg__ + 1089 0062 B104 cpc r11,__zero_reg__ + 1090 0064 01F0 breq .L57 + 1091 0066 8816 cp r8,r24 + 1092 0068 9906 cpc r9,r25 + 1093 006a AA06 cpc r10,r26 + 1094 006c BB06 cpc r11,r27 + 1095 006e 00F4 brsh .L57 + 1096 0070 00C0 rjmp .L58 + 1097 .LVL110: + 1098 .L56: + 1099 .LSM85: + 1100 0072 C101 movw r24,r2 + 1101 0074 0E94 0000 call get_fat + 1102 .LVL111: + 1103 0078 9B01 movw r18,r22 + 1104 007a AC01 movw r20,r24 + 1105 .LVL112: + 1106 .LSM86: + 1107 007c 6230 cpi r22,lo8(2) + 1108 007e 7105 cpc r23,__zero_reg__ + 1109 0080 8105 cpc r24,__zero_reg__ + 1110 0082 9105 cpc r25,__zero_reg__ + 1111 0084 00F4 brsh .L59 + 1112 .LVL113: + 1113 0086 21E0 ldi r18,lo8(1) + 1114 0088 30E0 ldi r19,hi8(1) + 1115 008a 40E0 ldi r20,hlo8(1) + 1116 008c 50E0 ldi r21,hhi8(1) + 1117 .LVL114: + 1118 008e 00C0 rjmp .L60 + 1119 .LVL115: + 1120 .L59: + 1121 .LSM87: + 1122 0090 8981 ldd r24,Y+1 + 1123 0092 9A81 ldd r25,Y+2 + 1124 0094 AB81 ldd r26,Y+3 + 1125 0096 BC81 ldd r27,Y+4 + 1126 0098 2817 cp r18,r24 + 1127 009a 3907 cpc r19,r25 + 1128 009c 4A07 cpc r20,r26 + 1129 009e 5B07 cpc r21,r27 + 1130 00a0 00F4 brsh .+2 + 1131 00a2 00C0 rjmp .L60 + 1132 .LVL116: + 1133 00a4 5301 movw r10,r6 + 1134 00a6 4201 movw r8,r4 + 1135 .LVL117: + 1136 00a8 00C0 rjmp .L58 + 1137 .LVL118: + 1138 .L57: + 1139 00aa 61E0 ldi r22,lo8(1) + 1140 00ac 862E mov r8,r22 + 1141 00ae 912C mov r9,__zero_reg__ + 1142 00b0 A12C mov r10,__zero_reg__ + 1143 00b2 B12C mov r11,__zero_reg__ + 1144 .LVL119: + 1145 .L58: + 1146 00b4 7501 movw r14,r10 + 1147 00b6 6401 movw r12,r8 + 1148 .LVL120: + 1149 .L64: + 1150 .LSM88: + 1151 00b8 0894 sec + 1152 00ba C11C adc r12,__zero_reg__ + 1153 00bc D11C adc r13,__zero_reg__ + 1154 00be E11C adc r14,__zero_reg__ + 1155 00c0 F11C adc r15,__zero_reg__ + 1156 .LSM89: + 1157 00c2 8981 ldd r24,Y+1 + 1158 00c4 9A81 ldd r25,Y+2 + 1159 00c6 AB81 ldd r26,Y+3 + 1160 00c8 BC81 ldd r27,Y+4 + 1161 00ca C816 cp r12,r24 + 1162 00cc D906 cpc r13,r25 + 1163 00ce EA06 cpc r14,r26 + 1164 00d0 FB06 cpc r15,r27 + 1165 00d2 00F0 brlo .L61 + 1166 .LSM90: + 1167 00d4 92E0 ldi r25,lo8(2) + 1168 00d6 8916 cp r8,r25 + 1169 00d8 9104 cpc r9,__zero_reg__ + 1170 00da A104 cpc r10,__zero_reg__ + 1171 00dc B104 cpc r11,__zero_reg__ + 1172 00de 00F4 brsh .+2 + 1173 00e0 00C0 rjmp .L62 + 1174 00e2 52E0 ldi r21,lo8(2) + 1175 00e4 C52E mov r12,r21 + 1176 00e6 D12C mov r13,__zero_reg__ + 1177 00e8 E12C mov r14,__zero_reg__ + 1178 00ea F12C mov r15,__zero_reg__ + 1179 .L61: + 1180 .LSM91: + 1181 00ec C101 movw r24,r2 + 1182 00ee B701 movw r22,r14 + 1183 00f0 A601 movw r20,r12 + 1184 00f2 0E94 0000 call get_fat + 1185 .LVL121: + 1186 00f6 9B01 movw r18,r22 + 1187 00f8 AC01 movw r20,r24 + 1188 .LVL122: + 1189 .LSM92: + 1190 00fa 6115 cp r22,__zero_reg__ + 1191 00fc 7105 cpc r23,__zero_reg__ + 1192 00fe 8105 cpc r24,__zero_reg__ + 1193 0100 9105 cpc r25,__zero_reg__ + 1194 0102 01F0 breq .L63 + 1195 .LVL123: + 1196 .LSM93: + 1197 0104 6F3F cpi r22,lo8(-1) + 1198 0106 AFEF ldi r26,hi8(-1) + 1199 0108 7A07 cpc r23,r26 + 1200 010a AFEF ldi r26,hlo8(-1) + 1201 010c 8A07 cpc r24,r26 + 1202 010e AFEF ldi r26,hhi8(-1) + 1203 0110 9A07 cpc r25,r26 + 1204 0112 01F4 brne .+2 + 1205 0114 00C0 rjmp .L60 + 1206 0116 6130 cpi r22,lo8(1) + 1207 0118 7105 cpc r23,__zero_reg__ + 1208 011a 8105 cpc r24,__zero_reg__ + 1209 011c 9105 cpc r25,__zero_reg__ + 1210 011e 01F4 brne .+2 + 1211 0120 00C0 rjmp .L60 + 1212 .LSM94: + 1213 0122 C814 cp r12,r8 + 1214 0124 D904 cpc r13,r9 + 1215 0126 EA04 cpc r14,r10 + 1216 0128 FB04 cpc r15,r11 + 1217 012a 01F4 brne .L64 + 1218 012c 00C0 rjmp .L62 + 1219 .L63: + 1220 012e BC2C mov r11,r12 + 1221 0130 AD2C mov r10,r13 + 1222 .LVL124: + 1223 0132 9E2C mov r9,r14 + 1224 .LVL125: + 1225 0134 8F2C mov r8,r15 + 1226 .LVL126: + 1227 .LSM95: + 1228 0136 C101 movw r24,r2 + 1229 0138 A601 movw r20,r12 + 1230 .LVL127: + 1231 013a B701 movw r22,r14 + 1232 .LVL128: + 1233 013c 0FEF ldi r16,lo8(268435455) + 1234 013e 1FEF ldi r17,hi8(268435455) + 1235 0140 2FEF ldi r18,hlo8(268435455) + 1236 0142 3FE0 ldi r19,hhi8(268435455) + 1237 0144 0E94 0000 call put_fat + 1238 .LVL129: + 1239 0148 8823 tst r24 + 1240 014a 01F4 brne .L65 + 1241 .LVL130: + 1242 .LSM96: + 1243 014c 4114 cp r4,__zero_reg__ + 1244 014e 5104 cpc r5,__zero_reg__ + 1245 0150 6104 cpc r6,__zero_reg__ + 1246 0152 7104 cpc r7,__zero_reg__ + 1247 0154 01F0 breq .L66 + 1248 .LSM97: + 1249 0156 C101 movw r24,r2 + 1250 0158 B301 movw r22,r6 + 1251 015a A201 movw r20,r4 + 1252 015c 8601 movw r16,r12 + 1253 015e 9701 movw r18,r14 + 1254 0160 0E94 0000 call put_fat + 1255 0164 8823 tst r24 + 1256 0166 01F4 brne .L65 + 1257 .L66: + 1258 .LSM98: + 1259 0168 F101 movw r30,r2 + 1260 016a B286 std Z+10,r11 + 1261 016c A386 std Z+11,r10 + 1262 016e 9486 std Z+12,r9 + 1263 0170 8586 std Z+13,r8 + 1264 .LSM99: + 1265 0172 8685 ldd r24,Z+14 + 1266 0174 9785 ldd r25,Z+15 + 1267 0176 A089 ldd r26,Z+16 + 1268 0178 B189 ldd r27,Z+17 + 1269 017a 8F3F cpi r24,lo8(-1) + 1270 017c FFEF ldi r31,hi8(-1) + 1271 017e 9F07 cpc r25,r31 + 1272 0180 FFEF ldi r31,hlo8(-1) + 1273 0182 AF07 cpc r26,r31 + 1274 0184 FFEF ldi r31,hhi8(-1) + 1275 0186 BF07 cpc r27,r31 + 1276 0188 01F0 breq .L69 + 1277 .L67: + 1278 .LSM100: + 1279 018a 0197 sbiw r24,1 + 1280 018c A109 sbc r26,__zero_reg__ + 1281 018e B109 sbc r27,__zero_reg__ + 1282 0190 F101 movw r30,r2 + 1283 0192 8687 std Z+14,r24 + 1284 0194 9787 std Z+15,r25 + 1285 0196 A08B std Z+16,r26 + 1286 0198 B18B std Z+17,r27 + 1287 .LSM101: + 1288 019a 81E0 ldi r24,lo8(1) + 1289 019c 8583 std Z+5,r24 + 1290 .L69: + 1291 019e A701 movw r20,r14 + 1292 01a0 9601 movw r18,r12 + 1293 .LVL131: + 1294 01a2 00C0 rjmp .L60 + 1295 .LVL132: + 1296 .L62: + 1297 01a4 20E0 ldi r18,lo8(0) + 1298 01a6 30E0 ldi r19,hi8(0) + 1299 01a8 40E0 ldi r20,hlo8(0) + 1300 01aa 50E0 ldi r21,hhi8(0) + 1301 01ac 00C0 rjmp .L60 + 1302 .LVL133: + 1303 .L65: + 1304 01ae 2FEF ldi r18,lo8(-1) + 1305 01b0 3FEF ldi r19,hi8(-1) + 1306 01b2 4FEF ldi r20,hlo8(-1) + 1307 01b4 5FEF ldi r21,hhi8(-1) + 1308 .LVL134: + 1309 .L60: + 1310 .LSM102: + 1311 01b6 B901 movw r22,r18 + 1312 .LVL135: + 1313 01b8 CA01 movw r24,r20 + 1314 /* epilogue start */ + 1315 01ba 0F90 pop __tmp_reg__ + 1316 01bc 0F90 pop __tmp_reg__ + 1317 01be 0F90 pop __tmp_reg__ + 1318 01c0 0F90 pop __tmp_reg__ + 1319 01c2 CF91 pop r28 + 1320 01c4 DF91 pop r29 + 1321 01c6 1F91 pop r17 + 1322 01c8 0F91 pop r16 + 1323 01ca FF90 pop r15 + 1324 01cc EF90 pop r14 + 1325 01ce DF90 pop r13 + 1326 01d0 CF90 pop r12 + 1327 .LVL136: + 1328 01d2 BF90 pop r11 + 1329 .LVL137: + 1330 01d4 AF90 pop r10 + 1331 .LVL138: + 1332 01d6 9F90 pop r9 + 1333 .LVL139: + 1334 01d8 8F90 pop r8 + 1335 .LVL140: + 1336 01da 7F90 pop r7 + 1337 01dc 6F90 pop r6 + 1338 01de 5F90 pop r5 + 1339 01e0 4F90 pop r4 + 1340 .LVL141: + 1341 01e2 3F90 pop r3 + 1342 01e4 2F90 pop r2 + 1343 .LVL142: + 1344 01e6 0895 ret + 1345 .LFE61: + 1347 .section .text.f_lseek,"ax",@progbits + 1348 .global f_lseek + 1350 f_lseek: + 1351 .LFB78: + 1352 .LSM103: + 1353 .LVL143: + 1354 0000 2F92 push r2 + 1355 0002 3F92 push r3 + 1356 0004 4F92 push r4 + 1357 0006 5F92 push r5 + 1358 0008 6F92 push r6 + 1359 000a 7F92 push r7 + 1360 000c 8F92 push r8 + 1361 000e 9F92 push r9 + 1362 0010 AF92 push r10 + 1363 0012 BF92 push r11 + 1364 0014 CF92 push r12 + 1365 0016 DF92 push r13 + 1366 0018 EF92 push r14 + 1367 001a FF92 push r15 + 1368 001c 0F93 push r16 + 1369 001e 1F93 push r17 + 1370 0020 DF93 push r29 + 1371 0022 CF93 push r28 + 1372 0024 00D0 rcall . + 1373 0026 00D0 rcall . + 1374 0028 0F92 push __tmp_reg__ + 1375 002a CDB7 in r28,__SP_L__ + 1376 002c DEB7 in r29,__SP_H__ + 1377 /* prologue: function */ + 1378 /* frame size = 5 */ + 1379 002e 9D83 std Y+5,r25 + 1380 0030 8C83 std Y+4,r24 + 1381 0032 3A01 movw r6,r20 + 1382 0034 4B01 movw r8,r22 + 1383 .LSM104: + 1384 0036 DC01 movw r26,r24 + 1385 0038 1296 adiw r26,2 + 1386 003a 6D91 ld r22,X+ + 1387 003c 7C91 ld r23,X + 1388 003e 1397 sbiw r26,2+1 + 1389 0040 8D91 ld r24,X+ + 1390 0042 9C91 ld r25,X + 1391 .LVL144: + 1392 0044 0E94 0000 call validate + 1393 .LVL145: + 1394 0048 8B83 std Y+3,r24 + 1395 .LVL146: + 1396 .LSM105: + 1397 004a 8823 tst r24 + 1398 004c 01F0 breq .+2 + 1399 004e 00C0 rjmp .L71 + 1400 .LSM106: + 1401 0050 EC81 ldd r30,Y+4 + 1402 0052 FD81 ldd r31,Y+5 + 1403 0054 8481 ldd r24,Z+4 + 1404 0056 87FD sbrc r24,7 + 1405 0058 00C0 rjmp .L94 + 1406 .L72: + 1407 .LSM107: + 1408 005a AC81 ldd r26,Y+4 + 1409 005c BD81 ldd r27,Y+5 + 1410 005e 1A96 adiw r26,10 + 1411 0060 AD90 ld r10,X+ + 1412 0062 BD90 ld r11,X+ + 1413 0064 CD90 ld r12,X+ + 1414 0066 DC90 ld r13,X + 1415 0068 1D97 sbiw r26,10+3 + 1416 .LVL147: + 1417 006a A614 cp r10,r6 + 1418 006c B704 cpc r11,r7 + 1419 006e C804 cpc r12,r8 + 1420 0070 D904 cpc r13,r9 + 1421 0072 00F4 brsh .L73 + 1422 0074 81FF sbrs r24,1 + 1423 0076 00C0 rjmp .L74 + 1424 .L73: + 1425 0078 6401 movw r12,r8 + 1426 007a 5301 movw r10,r6 + 1427 .L74: + 1428 .LSM108: + 1429 007c EC81 ldd r30,Y+4 + 1430 007e FD81 ldd r31,Y+5 + 1431 0080 2681 ldd r18,Z+6 + 1432 0082 3781 ldd r19,Z+7 + 1433 0084 4085 ldd r20,Z+8 + 1434 0086 5185 ldd r21,Z+9 + 1435 .LVL148: + 1436 .LSM109: + 1437 0088 1682 std Z+6,__zero_reg__ + 1438 008a 1782 std Z+7,__zero_reg__ + 1439 008c 1086 std Z+8,__zero_reg__ + 1440 008e 1186 std Z+9,__zero_reg__ + 1441 0090 8FEF ldi r24,lo8(-1) + 1442 0092 8583 std Z+5,r24 + 1443 .LSM110: + 1444 0094 A114 cp r10,__zero_reg__ + 1445 0096 B104 cpc r11,__zero_reg__ + 1446 0098 C104 cpc r12,__zero_reg__ + 1447 009a D104 cpc r13,__zero_reg__ + 1448 009c 01F4 brne .+2 + 1449 009e 00C0 rjmp .L75 + 1450 .LSM111: + 1451 00a0 0190 ld __tmp_reg__,Z+ + 1452 00a2 F081 ld r31,Z + 1453 00a4 E02D mov r30,__tmp_reg__ + 1454 00a6 FA83 std Y+2,r31 + 1455 00a8 E983 std Y+1,r30 + 1456 00aa 8281 ldd r24,Z+2 + 1457 00ac 682E mov r6,r24 + 1458 .LVL149: + 1459 00ae 7724 clr r7 + 1460 .LVL150: + 1461 00b0 8824 clr r8 + 1462 00b2 9924 clr r9 + 1463 .LVL151: + 1464 00b4 09E0 ldi r16,9 + 1465 00b6 660C 1: lsl r6 + 1466 00b8 771C rol r7 + 1467 00ba 881C rol r8 + 1468 00bc 991C rol r9 + 1469 00be 0A95 dec r16 + 1470 00c0 01F4 brne 1b + 1471 .LVL152: + 1472 .LSM112: + 1473 00c2 2115 cp r18,__zero_reg__ + 1474 00c4 3105 cpc r19,__zero_reg__ + 1475 00c6 4105 cpc r20,__zero_reg__ + 1476 00c8 5105 cpc r21,__zero_reg__ + 1477 00ca 01F0 breq .L76 + 1478 00cc 1901 movw r2,r18 + 1479 00ce 2A01 movw r4,r20 + 1480 00d0 0894 sec + 1481 00d2 2108 sbc r2,__zero_reg__ + 1482 00d4 3108 sbc r3,__zero_reg__ + 1483 00d6 4108 sbc r4,__zero_reg__ + 1484 00d8 5108 sbc r5,__zero_reg__ + 1485 00da C601 movw r24,r12 + 1486 00dc B501 movw r22,r10 + 1487 00de 6150 subi r22,lo8(-(-1)) + 1488 00e0 7040 sbci r23,hi8(-(-1)) + 1489 00e2 8040 sbci r24,hlo8(-(-1)) + 1490 00e4 9040 sbci r25,hhi8(-(-1)) + 1491 00e6 A401 movw r20,r8 + 1492 00e8 9301 movw r18,r6 + 1493 .LVL153: + 1494 00ea 0E94 0000 call __udivmodsi4 + 1495 00ee 7901 movw r14,r18 + 1496 00f0 8A01 movw r16,r20 + 1497 00f2 C201 movw r24,r4 + 1498 00f4 B101 movw r22,r2 + 1499 00f6 A401 movw r20,r8 + 1500 00f8 9301 movw r18,r6 + 1501 00fa 0E94 0000 call __udivmodsi4 + 1502 00fe E216 cp r14,r18 + 1503 0100 F306 cpc r15,r19 + 1504 0102 0407 cpc r16,r20 + 1505 0104 1507 cpc r17,r21 + 1506 0106 00F0 brlo .L76 + 1507 .LSM113: + 1508 0108 8827 clr r24 + 1509 010a 9927 clr r25 + 1510 010c DC01 movw r26,r24 + 1511 010e 8619 sub r24,r6 + 1512 0110 9709 sbc r25,r7 + 1513 0112 A809 sbc r26,r8 + 1514 0114 B909 sbc r27,r9 + 1515 0116 8221 and r24,r2 + 1516 0118 9321 and r25,r3 + 1517 011a A421 and r26,r4 + 1518 011c B521 and r27,r5 + 1519 011e EC81 ldd r30,Y+4 + 1520 0120 FD81 ldd r31,Y+5 + 1521 0122 8683 std Z+6,r24 + 1522 0124 9783 std Z+7,r25 + 1523 0126 A087 std Z+8,r26 + 1524 0128 B187 std Z+9,r27 + 1525 .LSM114: + 1526 012a A81A sub r10,r24 + 1527 012c B90A sbc r11,r25 + 1528 012e CA0A sbc r12,r26 + 1529 0130 DB0A sbc r13,r27 + 1530 .LSM115: + 1531 0132 4289 ldd r20,Z+18 + 1532 0134 5389 ldd r21,Z+19 + 1533 0136 6489 ldd r22,Z+20 + 1534 0138 7589 ldd r23,Z+21 + 1535 .LVL154: + 1536 013a 00C0 rjmp .L77 + 1537 .LVL155: + 1538 .L76: + 1539 .LSM116: + 1540 013c AC81 ldd r26,Y+4 + 1541 013e BD81 ldd r27,Y+5 + 1542 0140 1E96 adiw r26,14 + 1543 0142 4D91 ld r20,X+ + 1544 0144 5D91 ld r21,X+ + 1545 0146 6D91 ld r22,X+ + 1546 0148 7C91 ld r23,X + 1547 014a 5197 sbiw r26,14+3 + 1548 .LVL156: + 1549 .LSM117: + 1550 014c 4115 cp r20,__zero_reg__ + 1551 014e 5105 cpc r21,__zero_reg__ + 1552 0150 6105 cpc r22,__zero_reg__ + 1553 0152 7105 cpc r23,__zero_reg__ + 1554 0154 01F4 brne .L78 + 1555 .LSM118: + 1556 0156 8981 ldd r24,Y+1 + 1557 0158 9A81 ldd r25,Y+2 + 1558 015a 40E0 ldi r20,lo8(0) + 1559 015c 50E0 ldi r21,hi8(0) + 1560 015e 60E0 ldi r22,hlo8(0) + 1561 0160 70E0 ldi r23,hhi8(0) + 1562 .LVL157: + 1563 0162 0E94 0000 call create_chain + 1564 .LVL158: + 1565 0166 AB01 movw r20,r22 + 1566 0168 BC01 movw r22,r24 + 1567 .LVL159: + 1568 .LSM119: + 1569 016a 4130 cpi r20,lo8(1) + 1570 016c 5105 cpc r21,__zero_reg__ + 1571 016e 6105 cpc r22,__zero_reg__ + 1572 0170 7105 cpc r23,__zero_reg__ + 1573 0172 01F4 brne .L79 + 1574 .L96: + 1575 0174 EC81 ldd r30,Y+4 + 1576 0176 FD81 ldd r31,Y+5 + 1577 0178 8481 ldd r24,Z+4 + 1578 017a 8068 ori r24,lo8(-128) + 1579 017c 8483 std Z+4,r24 + 1580 .LVL160: + 1581 .L94: + 1582 017e F2E0 ldi r31,lo8(2) + 1583 0180 FB83 std Y+3,r31 + 1584 .LVL161: + 1585 0182 00C0 rjmp .L71 + 1586 .LVL162: + 1587 .L79: + 1588 .LSM120: + 1589 0184 4F3F cpi r20,lo8(-1) + 1590 0186 8FEF ldi r24,hi8(-1) + 1591 0188 5807 cpc r21,r24 + 1592 018a 8FEF ldi r24,hlo8(-1) + 1593 018c 6807 cpc r22,r24 + 1594 018e 8FEF ldi r24,hhi8(-1) + 1595 0190 7807 cpc r23,r24 + 1596 0192 01F0 breq .L97 + 1597 .L80: + 1598 .LSM121: + 1599 0194 EC81 ldd r30,Y+4 + 1600 0196 FD81 ldd r31,Y+5 + 1601 0198 4687 std Z+14,r20 + 1602 019a 5787 std Z+15,r21 + 1603 019c 608B std Z+16,r22 + 1604 019e 718B std Z+17,r23 + 1605 .LVL163: + 1606 .L78: + 1607 .LSM122: + 1608 01a0 AC81 ldd r26,Y+4 + 1609 01a2 BD81 ldd r27,Y+5 + 1610 01a4 5296 adiw r26,18 + 1611 01a6 4D93 st X+,r20 + 1612 01a8 5D93 st X+,r21 + 1613 01aa 6D93 st X+,r22 + 1614 01ac 7C93 st X,r23 + 1615 01ae 5597 sbiw r26,18+3 + 1616 .L77: + 1617 .LSM123: + 1618 01b0 4115 cp r20,__zero_reg__ + 1619 01b2 5105 cpc r21,__zero_reg__ + 1620 01b4 6105 cpc r22,__zero_reg__ + 1621 01b6 7105 cpc r23,__zero_reg__ + 1622 01b8 01F0 breq .+2 + 1623 01ba 00C0 rjmp .L93 + 1624 01bc 00C0 rjmp .L75 + 1625 .L88: + 1626 .LSM124: + 1627 01be EC81 ldd r30,Y+4 + 1628 01c0 FD81 ldd r31,Y+5 + 1629 01c2 8481 ldd r24,Z+4 + 1630 01c4 2081 ld r18,Z + 1631 01c6 3181 ldd r19,Z+1 + 1632 .LVL164: + 1633 01c8 81FF sbrs r24,1 + 1634 01ca 00C0 rjmp .L82 + 1635 .LSM125: + 1636 01cc C901 movw r24,r18 + 1637 01ce 0E94 0000 call create_chain + 1638 .LVL165: + 1639 01d2 AB01 movw r20,r22 + 1640 01d4 BC01 movw r22,r24 + 1641 .LVL166: + 1642 .LSM126: + 1643 01d6 4115 cp r20,__zero_reg__ + 1644 01d8 5105 cpc r21,__zero_reg__ + 1645 01da 6105 cpc r22,__zero_reg__ + 1646 01dc 7105 cpc r23,__zero_reg__ + 1647 01de 01F4 brne .L83 + 1648 01e0 6401 movw r12,r8 + 1649 01e2 5301 movw r10,r6 + 1650 01e4 00C0 rjmp .L84 + 1651 .L82: + 1652 .LSM127: + 1653 01e6 C901 movw r24,r18 + 1654 01e8 0E94 0000 call get_fat + 1655 .LVL167: + 1656 01ec AB01 movw r20,r22 + 1657 01ee BC01 movw r22,r24 + 1658 .LVL168: + 1659 .L83: + 1660 .LSM128: + 1661 01f0 4F3F cpi r20,lo8(-1) + 1662 01f2 FFEF ldi r31,hi8(-1) + 1663 01f4 5F07 cpc r21,r31 + 1664 01f6 FFEF ldi r31,hlo8(-1) + 1665 01f8 6F07 cpc r22,r31 + 1666 01fa FFEF ldi r31,hhi8(-1) + 1667 01fc 7F07 cpc r23,r31 + 1668 01fe 01F4 brne .L85 + 1669 .L97: + 1670 0200 AC81 ldd r26,Y+4 + 1671 0202 BD81 ldd r27,Y+5 + 1672 0204 1496 adiw r26,4 + 1673 0206 8C91 ld r24,X + 1674 0208 1497 sbiw r26,4 + 1675 020a 8068 ori r24,lo8(-128) + 1676 020c 1496 adiw r26,4 + 1677 020e 8C93 st X,r24 + 1678 0210 B1E0 ldi r27,lo8(1) + 1679 0212 00C0 rjmp .L95 + 1680 .L85: + 1681 .LSM129: + 1682 0214 4230 cpi r20,lo8(2) + 1683 0216 5105 cpc r21,__zero_reg__ + 1684 0218 6105 cpc r22,__zero_reg__ + 1685 021a 7105 cpc r23,__zero_reg__ + 1686 021c 00F4 brsh .+2 + 1687 021e 00C0 rjmp .L96 + 1688 0220 AC81 ldd r26,Y+4 + 1689 0222 BD81 ldd r27,Y+5 + 1690 0224 ED91 ld r30,X+ + 1691 0226 FC91 ld r31,X + 1692 0228 828D ldd r24,Z+26 + 1693 022a 938D ldd r25,Z+27 + 1694 022c A48D ldd r26,Z+28 + 1695 022e B58D ldd r27,Z+29 + 1696 0230 4817 cp r20,r24 + 1697 0232 5907 cpc r21,r25 + 1698 0234 6A07 cpc r22,r26 + 1699 0236 7B07 cpc r23,r27 + 1700 0238 00F0 brlo .+2 + 1701 023a 00C0 rjmp .L96 + 1702 .L87: + 1703 .LSM130: + 1704 023c AC81 ldd r26,Y+4 + 1705 023e BD81 ldd r27,Y+5 + 1706 0240 5296 adiw r26,18 + 1707 0242 4D93 st X+,r20 + 1708 0244 5D93 st X+,r21 + 1709 0246 6D93 st X+,r22 + 1710 0248 7C93 st X,r23 + 1711 024a 5597 sbiw r26,18+3 + 1712 .LSM131: + 1713 024c FD01 movw r30,r26 + 1714 024e 8681 ldd r24,Z+6 + 1715 0250 9781 ldd r25,Z+7 + 1716 0252 A085 ldd r26,Z+8 + 1717 0254 B185 ldd r27,Z+9 + 1718 0256 860D add r24,r6 + 1719 0258 971D adc r25,r7 + 1720 025a A81D adc r26,r8 + 1721 025c B91D adc r27,r9 + 1722 025e 8683 std Z+6,r24 + 1723 0260 9783 std Z+7,r25 + 1724 0262 A087 std Z+8,r26 + 1725 0264 B187 std Z+9,r27 + 1726 .LSM132: + 1727 0266 A618 sub r10,r6 + 1728 0268 B708 sbc r11,r7 + 1729 026a C808 sbc r12,r8 + 1730 026c D908 sbc r13,r9 + 1731 .LVL169: + 1732 .L93: + 1733 .LSM133: + 1734 026e 6A14 cp r6,r10 + 1735 0270 7B04 cpc r7,r11 + 1736 0272 8C04 cpc r8,r12 + 1737 0274 9D04 cpc r9,r13 + 1738 0276 00F4 brsh .+2 + 1739 0278 00C0 rjmp .L88 + 1740 .L84: + 1741 .LSM134: + 1742 027a EC81 ldd r30,Y+4 + 1743 027c FD81 ldd r31,Y+5 + 1744 027e 8681 ldd r24,Z+6 + 1745 0280 9781 ldd r25,Z+7 + 1746 0282 A085 ldd r26,Z+8 + 1747 0284 B185 ldd r27,Z+9 + 1748 0286 8A0D add r24,r10 + 1749 0288 9B1D adc r25,r11 + 1750 028a AC1D adc r26,r12 + 1751 028c BD1D adc r27,r13 + 1752 028e 8683 std Z+6,r24 + 1753 0290 9783 std Z+7,r25 + 1754 0292 A087 std Z+8,r26 + 1755 0294 B187 std Z+9,r27 + 1756 .LSM135: + 1757 0296 D601 movw r26,r12 + 1758 0298 C501 movw r24,r10 + 1759 029a 19E0 ldi r17,9 + 1760 029c B695 1: lsr r27 + 1761 029e A795 ror r26 + 1762 02a0 9795 ror r25 + 1763 02a2 8795 ror r24 + 1764 02a4 1A95 dec r17 + 1765 02a6 01F4 brne 1b + 1766 02a8 E82E mov r14,r24 + 1767 02aa 8583 std Z+5,r24 + 1768 .LSM136: + 1769 02ac 8FEF ldi r24,lo8(511) + 1770 02ae 91E0 ldi r25,hi8(511) + 1771 02b0 A0E0 ldi r26,hlo8(511) + 1772 02b2 B0E0 ldi r27,hhi8(511) + 1773 02b4 A822 and r10,r24 + 1774 02b6 B922 and r11,r25 + 1775 02b8 CA22 and r12,r26 + 1776 02ba DB22 and r13,r27 + 1777 02bc A114 cp r10,__zero_reg__ + 1778 02be B104 cpc r11,__zero_reg__ + 1779 02c0 C104 cpc r12,__zero_reg__ + 1780 02c2 D104 cpc r13,__zero_reg__ + 1781 02c4 01F0 breq .L75 + 1782 .LSM137: + 1783 02c6 8081 ld r24,Z + 1784 02c8 9181 ldd r25,Z+1 + 1785 02ca 0E94 0000 call clust2sect + 1786 .LVL170: + 1787 .LSM138: + 1788 02ce 6115 cp r22,__zero_reg__ + 1789 02d0 7105 cpc r23,__zero_reg__ + 1790 02d2 8105 cpc r24,__zero_reg__ + 1791 02d4 9105 cpc r25,__zero_reg__ + 1792 .LVL171: + 1793 02d6 01F4 brne .L89 + 1794 02d8 AC81 ldd r26,Y+4 + 1795 02da BD81 ldd r27,Y+5 + 1796 02dc 1496 adiw r26,4 + 1797 02de 8C91 ld r24,X + 1798 02e0 1497 sbiw r26,4 + 1799 02e2 8068 ori r24,lo8(-128) + 1800 02e4 1496 adiw r26,4 + 1801 02e6 8C93 st X,r24 + 1802 02e8 B2E0 ldi r27,lo8(2) + 1803 .LVL172: + 1804 .L95: + 1805 02ea BB83 std Y+3,r27 + 1806 .LVL173: + 1807 02ec 00C0 rjmp .L71 + 1808 .LVL174: + 1809 .L89: + 1810 .LSM139: + 1811 02ee 9B01 movw r18,r22 + 1812 02f0 AC01 movw r20,r24 + 1813 02f2 2E0D add r18,r14 + 1814 02f4 311D adc r19,__zero_reg__ + 1815 02f6 411D adc r20,__zero_reg__ + 1816 02f8 511D adc r21,__zero_reg__ + 1817 .LVL175: + 1818 .LSM140: + 1819 02fa E394 inc r14 + 1820 02fc EC81 ldd r30,Y+4 + 1821 02fe FD81 ldd r31,Y+5 + 1822 0300 E582 std Z+5,r14 + 1823 0302 00C0 rjmp .L90 + 1824 .LVL176: + 1825 .L75: + 1826 0304 20E0 ldi r18,lo8(0) + 1827 0306 30E0 ldi r19,hi8(0) + 1828 0308 40E0 ldi r20,hlo8(0) + 1829 030a 50E0 ldi r21,hhi8(0) + 1830 .LVL177: + 1831 .L90: + 1832 .LSM141: + 1833 030c EC81 ldd r30,Y+4 + 1834 030e FD81 ldd r31,Y+5 + 1835 0310 8681 ldd r24,Z+6 + 1836 0312 9781 ldd r25,Z+7 + 1837 0314 A085 ldd r26,Z+8 + 1838 0316 B185 ldd r27,Z+9 + 1839 0318 9170 andi r25,hi8(511) + 1840 031a A070 andi r26,hlo8(511) + 1841 031c B070 andi r27,hhi8(511) + 1842 031e 0097 sbiw r24,0 + 1843 0320 A105 cpc r26,__zero_reg__ + 1844 0322 B105 cpc r27,__zero_reg__ + 1845 0324 01F0 breq .L91 + 1846 0326 8689 ldd r24,Z+22 + 1847 0328 9789 ldd r25,Z+23 + 1848 032a A08D ldd r26,Z+24 + 1849 032c B18D ldd r27,Z+25 + 1850 032e 2817 cp r18,r24 + 1851 0330 3907 cpc r19,r25 + 1852 0332 4A07 cpc r20,r26 + 1853 0334 5B07 cpc r21,r27 + 1854 0336 01F0 breq .L91 + 1855 .LSM142: + 1856 0338 268B std Z+22,r18 + 1857 033a 378B std Z+23,r19 + 1858 033c 408F std Z+24,r20 + 1859 033e 518F std Z+25,r21 + 1860 .L91: + 1861 .LSM143: + 1862 0340 EC81 ldd r30,Y+4 + 1863 0342 FD81 ldd r31,Y+5 + 1864 0344 2681 ldd r18,Z+6 + 1865 0346 3781 ldd r19,Z+7 + 1866 0348 4085 ldd r20,Z+8 + 1867 034a 5185 ldd r21,Z+9 + 1868 .LVL178: + 1869 034c 8285 ldd r24,Z+10 + 1870 034e 9385 ldd r25,Z+11 + 1871 0350 A485 ldd r26,Z+12 + 1872 0352 B585 ldd r27,Z+13 + 1873 0354 8217 cp r24,r18 + 1874 0356 9307 cpc r25,r19 + 1875 0358 A407 cpc r26,r20 + 1876 035a B507 cpc r27,r21 + 1877 035c 00F4 brsh .L71 + 1878 .LSM144: + 1879 035e 2287 std Z+10,r18 + 1880 0360 3387 std Z+11,r19 + 1881 0362 4487 std Z+12,r20 + 1882 0364 5587 std Z+13,r21 + 1883 .LSM145: + 1884 0366 8481 ldd r24,Z+4 + 1885 0368 8062 ori r24,lo8(32) + 1886 036a 8483 std Z+4,r24 + 1887 .LVL179: + 1888 .L71: + 1889 .LSM146: + 1890 036c 8B81 ldd r24,Y+3 + 1891 /* epilogue start */ + 1892 036e 0F90 pop __tmp_reg__ + 1893 0370 0F90 pop __tmp_reg__ + 1894 0372 0F90 pop __tmp_reg__ + 1895 0374 0F90 pop __tmp_reg__ + 1896 0376 0F90 pop __tmp_reg__ + 1897 0378 CF91 pop r28 + 1898 037a DF91 pop r29 + 1899 037c 1F91 pop r17 + 1900 037e 0F91 pop r16 + 1901 0380 FF90 pop r15 + 1902 0382 EF90 pop r14 + 1903 0384 DF90 pop r13 + 1904 0386 CF90 pop r12 + 1905 0388 BF90 pop r11 + 1906 038a AF90 pop r10 + 1907 .LVL180: + 1908 038c 9F90 pop r9 + 1909 038e 8F90 pop r8 + 1910 .LVL181: + 1911 0390 7F90 pop r7 + 1912 .LVL182: + 1913 0392 6F90 pop r6 + 1914 .LVL183: + 1915 0394 5F90 pop r5 + 1916 0396 4F90 pop r4 + 1917 0398 3F90 pop r3 + 1918 039a 2F90 pop r2 + 1919 039c 0895 ret + 1920 .LFE78: + 1922 .section .text.dir_seek,"ax",@progbits + 1924 dir_seek: + 1925 .LFB63: + 1926 .LSM147: + 1927 .LVL184: + 1928 0000 EF92 push r14 + 1929 0002 FF92 push r15 + 1930 0004 0F93 push r16 + 1931 0006 1F93 push r17 + 1932 0008 CF93 push r28 + 1933 000a DF93 push r29 + 1934 /* prologue: function */ + 1935 /* frame size = 0 */ + 1936 000c 8C01 movw r16,r24 + 1937 000e EB01 movw r28,r22 + 1938 .LSM148: + 1939 0010 DC01 movw r26,r24 + 1940 0012 1596 adiw r26,4+1 + 1941 0014 7C93 st X,r23 + 1942 0016 6E93 st -X,r22 + 1943 0018 1497 sbiw r26,4 + 1944 .LSM149: + 1945 001a 1696 adiw r26,6 + 1946 001c 4D91 ld r20,X+ + 1947 001e 5D91 ld r21,X+ + 1948 0020 6D91 ld r22,X+ + 1949 0022 7C91 ld r23,X + 1950 0024 1997 sbiw r26,6+3 + 1951 .LVL185: + 1952 .LSM150: + 1953 0026 4130 cpi r20,lo8(1) + 1954 0028 5105 cpc r21,__zero_reg__ + 1955 002a 6105 cpc r22,__zero_reg__ + 1956 002c 7105 cpc r23,__zero_reg__ + 1957 002e 01F4 brne .+2 + 1958 0030 00C0 rjmp .L99 + 1959 0032 ED91 ld r30,X+ + 1960 0034 FC91 ld r31,X + 1961 0036 828D ldd r24,Z+26 + 1962 0038 938D ldd r25,Z+27 + 1963 003a A48D ldd r26,Z+28 + 1964 003c B58D ldd r27,Z+29 + 1965 .LVL186: + 1966 003e 4817 cp r20,r24 + 1967 0040 5907 cpc r21,r25 + 1968 0042 6A07 cpc r22,r26 + 1969 0044 7B07 cpc r23,r27 + 1970 0046 00F0 brlo .+2 + 1971 0048 00C0 rjmp .L99 + 1972 .LSM151: + 1973 004a 4115 cp r20,__zero_reg__ + 1974 004c 5105 cpc r21,__zero_reg__ + 1975 004e 6105 cpc r22,__zero_reg__ + 1976 0050 7105 cpc r23,__zero_reg__ + 1977 0052 01F4 brne .L100 + 1978 0054 8081 ld r24,Z + 1979 0056 8330 cpi r24,lo8(3) + 1980 0058 01F4 brne .L101 + 1981 .LSM152: + 1982 005a 42A1 ldd r20,Z+34 + 1983 005c 53A1 ldd r21,Z+35 + 1984 005e 64A1 ldd r22,Z+36 + 1985 0060 75A1 ldd r23,Z+37 + 1986 .LSM153: + 1987 0062 4115 cp r20,__zero_reg__ + 1988 0064 5105 cpc r21,__zero_reg__ + 1989 0066 6105 cpc r22,__zero_reg__ + 1990 0068 7105 cpc r23,__zero_reg__ + 1991 006a 01F4 brne .L100 + 1992 .L101: + 1993 .LSM154: + 1994 006c F801 movw r30,r16 + 1995 006e 1286 std Z+10,__zero_reg__ + 1996 0070 1386 std Z+11,__zero_reg__ + 1997 0072 1486 std Z+12,__zero_reg__ + 1998 0074 1586 std Z+13,__zero_reg__ + 1999 .LSM155: + 2000 0076 0190 ld __tmp_reg__,Z+ + 2001 0078 F081 ld r31,Z + 2002 007a E02D mov r30,__tmp_reg__ + 2003 007c 8085 ldd r24,Z+8 + 2004 007e 9185 ldd r25,Z+9 + 2005 0080 C817 cp r28,r24 + 2006 0082 D907 cpc r29,r25 + 2007 0084 00F0 brlo .+2 + 2008 0086 00C0 rjmp .L99 + 2009 .LVL187: + 2010 .LSM156: + 2011 0088 CE01 movw r24,r28 + 2012 008a A4E0 ldi r26,4 + 2013 008c 9695 1: lsr r25 + 2014 008e 8795 ror r24 + 2015 0090 AA95 dec r26 + 2016 0092 01F4 brne 1b + 2017 0094 A0E0 ldi r26,lo8(0) + 2018 0096 B0E0 ldi r27,hi8(0) + 2019 0098 22A1 ldd r18,Z+34 + 2020 009a 33A1 ldd r19,Z+35 + 2021 009c 44A1 ldd r20,Z+36 + 2022 009e 55A1 ldd r21,Z+37 + 2023 00a0 820F add r24,r18 + 2024 00a2 931F adc r25,r19 + 2025 00a4 A41F adc r26,r20 + 2026 00a6 B51F adc r27,r21 + 2027 00a8 F801 movw r30,r16 + 2028 00aa 8687 std Z+14,r24 + 2029 00ac 9787 std Z+15,r25 + 2030 00ae A08B std Z+16,r26 + 2031 00b0 B18B std Z+17,r27 + 2032 00b2 00C0 rjmp .L102 + 2033 .LVL188: + 2034 .L100: + 2035 .LSM157: + 2036 00b4 8281 ldd r24,Z+2 + 2037 00b6 E82E mov r14,r24 + 2038 .LVL189: + 2039 00b8 FF24 clr r15 + 2040 .LVL190: + 2041 00ba E4E0 ldi r30,4 + 2042 00bc EE0C 1: lsl r14 + 2043 00be FF1C rol r15 + 2044 00c0 EA95 dec r30 + 2045 00c2 01F4 brne 1b + 2046 .LVL191: + 2047 00c4 00C0 rjmp .L103 + 2048 .LVL192: + 2049 .L106: + 2050 .LSM158: + 2051 00c6 0E94 0000 call get_fat + 2052 .LVL193: + 2053 00ca AB01 movw r20,r22 + 2054 00cc BC01 movw r22,r24 + 2055 .LVL194: + 2056 .LSM159: + 2057 00ce 4F3F cpi r20,lo8(-1) + 2058 00d0 FFEF ldi r31,hi8(-1) + 2059 00d2 5F07 cpc r21,r31 + 2060 00d4 FFEF ldi r31,hlo8(-1) + 2061 00d6 6F07 cpc r22,r31 + 2062 00d8 FFEF ldi r31,hhi8(-1) + 2063 00da 7F07 cpc r23,r31 + 2064 00dc 01F4 brne .L104 + 2065 00de 81E0 ldi r24,lo8(1) + 2066 00e0 00C0 rjmp .L105 + 2067 .L104: + 2068 .LSM160: + 2069 00e2 4230 cpi r20,lo8(2) + 2070 00e4 5105 cpc r21,__zero_reg__ + 2071 00e6 6105 cpc r22,__zero_reg__ + 2072 00e8 7105 cpc r23,__zero_reg__ + 2073 00ea 00F4 brsh .+2 + 2074 00ec 00C0 rjmp .L99 + 2075 00ee D801 movw r26,r16 + 2076 00f0 ED91 ld r30,X+ + 2077 00f2 FC91 ld r31,X + 2078 00f4 828D ldd r24,Z+26 + 2079 00f6 938D ldd r25,Z+27 + 2080 00f8 A48D ldd r26,Z+28 + 2081 00fa B58D ldd r27,Z+29 + 2082 00fc 4817 cp r20,r24 + 2083 00fe 5907 cpc r21,r25 + 2084 0100 6A07 cpc r22,r26 + 2085 0102 7B07 cpc r23,r27 + 2086 0104 00F4 brsh .L99 + 2087 .LSM161: + 2088 0106 CE19 sub r28,r14 + 2089 0108 DF09 sbc r29,r15 + 2090 .LVL195: + 2091 .L103: + 2092 010a F801 movw r30,r16 + 2093 010c 8081 ld r24,Z + 2094 010e 9181 ldd r25,Z+1 + 2095 .LSM162: + 2096 0110 CE15 cp r28,r14 + 2097 0112 DF05 cpc r29,r15 + 2098 0114 00F4 brsh .L106 + 2099 .LSM163: + 2100 0116 D801 movw r26,r16 + 2101 0118 1A96 adiw r26,10 + 2102 011a 4D93 st X+,r20 + 2103 011c 5D93 st X+,r21 + 2104 011e 6D93 st X+,r22 + 2105 0120 7C93 st X,r23 + 2106 0122 1D97 sbiw r26,10+3 + 2107 .LSM164: + 2108 0124 0E94 0000 call clust2sect + 2109 .LVL196: + 2110 0128 9E01 movw r18,r28 + 2111 012a 44E0 ldi r20,4 + 2112 012c 3695 1: lsr r19 + 2113 012e 2795 ror r18 + 2114 0130 4A95 dec r20 + 2115 0132 01F4 brne 1b + 2116 0134 40E0 ldi r20,lo8(0) + 2117 0136 50E0 ldi r21,hi8(0) + 2118 0138 260F add r18,r22 + 2119 013a 371F adc r19,r23 + 2120 013c 481F adc r20,r24 + 2121 013e 591F adc r21,r25 + 2122 0140 F801 movw r30,r16 + 2123 0142 2687 std Z+14,r18 + 2124 0144 3787 std Z+15,r19 + 2125 0146 408B std Z+16,r20 + 2126 0148 518B std Z+17,r21 + 2127 .LVL197: + 2128 .L102: + 2129 .LSM165: + 2130 014a CF70 andi r28,lo8(15) + 2131 014c D070 andi r29,hi8(15) + 2132 014e 85E0 ldi r24,5 + 2133 0150 CC0F 1: lsl r28 + 2134 0152 DD1F rol r29 + 2135 0154 8A95 dec r24 + 2136 0156 01F4 brne 1b + 2137 0158 AE96 adiw r28,46 + 2138 015a D801 movw r26,r16 + 2139 015c 8D91 ld r24,X+ + 2140 015e 9C91 ld r25,X + 2141 0160 1197 sbiw r26,1 + 2142 0162 8C0F add r24,r28 + 2143 0164 9D1F adc r25,r29 + 2144 0166 5396 adiw r26,18+1 + 2145 0168 9C93 st X,r25 + 2146 016a 8E93 st -X,r24 + 2147 016c 5297 sbiw r26,18 + 2148 016e 80E0 ldi r24,lo8(0) + 2149 0170 00C0 rjmp .L105 + 2150 .LVL198: + 2151 .L99: + 2152 .LSM166: + 2153 0172 82E0 ldi r24,lo8(2) + 2154 .L105: + 2155 /* epilogue start */ + 2156 .LSM167: + 2157 0174 DF91 pop r29 + 2158 0176 CF91 pop r28 + 2159 .LVL199: + 2160 0178 1F91 pop r17 + 2161 017a 0F91 pop r16 + 2162 .LVL200: + 2163 017c FF90 pop r15 + 2164 .LVL201: + 2165 017e EF90 pop r14 + 2166 .LVL202: + 2167 0180 0895 ret + 2168 .LFE63: + 2170 .section .text.f_write,"ax",@progbits + 2171 .global f_write + 2173 f_write: + 2174 .LFB75: + 2175 .LSM168: + 2176 .LVL203: + 2177 0000 2F92 push r2 + 2178 0002 3F92 push r3 + 2179 0004 4F92 push r4 + 2180 0006 5F92 push r5 + 2181 0008 6F92 push r6 + 2182 000a 7F92 push r7 + 2183 000c 8F92 push r8 + 2184 000e 9F92 push r9 + 2185 0010 AF92 push r10 + 2186 0012 BF92 push r11 + 2187 0014 CF92 push r12 + 2188 0016 DF92 push r13 + 2189 0018 EF92 push r14 + 2190 001a FF92 push r15 + 2191 001c 0F93 push r16 + 2192 001e 1F93 push r17 + 2193 0020 CF93 push r28 + 2194 0022 DF93 push r29 + 2195 /* prologue: function */ + 2196 /* frame size = 0 */ + 2197 0024 EC01 movw r28,r24 + 2198 0026 162F mov r17,r22 + 2199 0028 072F mov r16,r23 + 2200 .LVL204: + 2201 002a 4A01 movw r8,r20 + 2202 002c 1901 movw r2,r18 + 2203 .LSM169: + 2204 002e F901 movw r30,r18 + 2205 0030 1182 std Z+1,__zero_reg__ + 2206 0032 1082 st Z,__zero_reg__ + 2207 .LSM170: + 2208 0034 6A81 ldd r22,Y+2 + 2209 0036 7B81 ldd r23,Y+3 + 2210 .LVL205: + 2211 0038 8881 ld r24,Y + 2212 003a 9981 ldd r25,Y+1 + 2213 .LVL206: + 2214 003c 0E94 0000 call validate + 2215 .LVL207: + 2216 0040 782E mov r7,r24 + 2217 .LVL208: + 2218 .LSM171: + 2219 0042 8823 tst r24 + 2220 0044 01F0 breq .+2 + 2221 0046 00C0 rjmp .L109 + 2222 .LVL209: + 2223 .LSM172: + 2224 0048 8C81 ldd r24,Y+4 + 2225 .LVL210: + 2226 004a 87FD sbrc r24,7 + 2227 004c 00C0 rjmp .L136 + 2228 .L110: + 2229 .LSM173: + 2230 004e 81FD sbrc r24,1 + 2231 0050 00C0 rjmp .L111 + 2232 0052 27E0 ldi r18,lo8(7) + 2233 0054 722E mov r7,r18 + 2234 0056 00C0 rjmp .L109 + 2235 .L111: + 2236 .LSM174: + 2237 0058 2A85 ldd r18,Y+10 + 2238 005a 3B85 ldd r19,Y+11 + 2239 005c 4C85 ldd r20,Y+12 + 2240 005e 5D85 ldd r21,Y+13 + 2241 0060 C401 movw r24,r8 + 2242 0062 A0E0 ldi r26,lo8(0) + 2243 0064 B0E0 ldi r27,hi8(0) + 2244 .LVL211: + 2245 0066 820F add r24,r18 + 2246 0068 931F adc r25,r19 + 2247 006a A41F adc r26,r20 + 2248 006c B51F adc r27,r21 + 2249 .LVL212: + 2250 006e 8217 cp r24,r18 + 2251 0070 9307 cpc r25,r19 + 2252 0072 A407 cpc r26,r20 + 2253 0074 B507 cpc r27,r21 + 2254 0076 00F4 brsh .L112 + 2255 0078 8824 clr r8 + 2256 007a 9924 clr r9 + 2257 .LVL213: + 2258 .L112: + 2259 .LSM175: + 2260 007c 812F mov r24,r17 + 2261 .LVL214: + 2262 007e 902F mov r25,r16 + 2263 .LVL215: + 2264 0080 9C01 movw r18,r24 + 2265 .LVL216: + 2266 0082 2901 movw r4,r18 + 2267 .LVL217: + 2268 .LSM176: + 2269 0084 6624 clr r6 + 2270 0086 6394 inc r6 + 2271 0088 00C0 rjmp .L113 + 2272 .LVL218: + 2273 .L133: + 2274 .LSM177: + 2275 008a 2E81 ldd r18,Y+6 + 2276 008c 3F81 ldd r19,Y+7 + 2277 008e 4885 ldd r20,Y+8 + 2278 0090 5985 ldd r21,Y+9 + 2279 0092 DA01 movw r26,r20 + 2280 0094 C901 movw r24,r18 + 2281 0096 9170 andi r25,hi8(511) + 2282 0098 A070 andi r26,hlo8(511) + 2283 009a B070 andi r27,hhi8(511) + 2284 009c 0097 sbiw r24,0 + 2285 009e A105 cpc r26,__zero_reg__ + 2286 00a0 B105 cpc r27,__zero_reg__ + 2287 00a2 01F0 breq .+2 + 2288 00a4 00C0 rjmp .L114 + 2289 .LSM178: + 2290 00a6 E881 ld r30,Y + 2291 00a8 F981 ldd r31,Y+1 + 2292 00aa 9D81 ldd r25,Y+5 + 2293 .LVL219: + 2294 00ac 8281 ldd r24,Z+2 + 2295 00ae 9817 cp r25,r24 + 2296 00b0 00F4 brsh .+2 + 2297 00b2 00C0 rjmp .L115 + 2298 .LSM179: + 2299 00b4 2115 cp r18,__zero_reg__ + 2300 00b6 3105 cpc r19,__zero_reg__ + 2301 00b8 4105 cpc r20,__zero_reg__ + 2302 00ba 5105 cpc r21,__zero_reg__ + 2303 00bc 01F4 brne .L116 + 2304 .LSM180: + 2305 00be 6E85 ldd r22,Y+14 + 2306 00c0 7F85 ldd r23,Y+15 + 2307 00c2 8889 ldd r24,Y+16 + 2308 00c4 9989 ldd r25,Y+17 + 2309 .LVL220: + 2310 .LSM181: + 2311 00c6 6115 cp r22,__zero_reg__ + 2312 00c8 7105 cpc r23,__zero_reg__ + 2313 00ca 8105 cpc r24,__zero_reg__ + 2314 00cc 9105 cpc r25,__zero_reg__ + 2315 00ce 01F4 brne .L117 + 2316 .LSM182: + 2317 00d0 CF01 movw r24,r30 + 2318 00d2 40E0 ldi r20,lo8(0) + 2319 00d4 50E0 ldi r21,hi8(0) + 2320 00d6 60E0 ldi r22,hlo8(0) + 2321 00d8 70E0 ldi r23,hhi8(0) + 2322 00da 0E94 0000 call create_chain + 2323 .LVL221: + 2324 00de 6E87 std Y+14,r22 + 2325 00e0 7F87 std Y+15,r23 + 2326 00e2 888B std Y+16,r24 + 2327 00e4 998B std Y+17,r25 + 2328 .LVL222: + 2329 00e6 00C0 rjmp .L118 + 2330 .LVL223: + 2331 .L116: + 2332 .LSM183: + 2333 00e8 4A89 ldd r20,Y+18 + 2334 00ea 5B89 ldd r21,Y+19 + 2335 00ec 6C89 ldd r22,Y+20 + 2336 00ee 7D89 ldd r23,Y+21 + 2337 00f0 CF01 movw r24,r30 + 2338 00f2 0E94 0000 call create_chain + 2339 .LVL224: + 2340 .L118: + 2341 .LSM184: + 2342 00f6 6115 cp r22,__zero_reg__ + 2343 00f8 7105 cpc r23,__zero_reg__ + 2344 00fa 8105 cpc r24,__zero_reg__ + 2345 00fc 9105 cpc r25,__zero_reg__ + 2346 00fe 01F4 brne .+2 + 2347 0100 00C0 rjmp .L119 + 2348 .LVL225: + 2349 .L117: + 2350 .LSM185: + 2351 0102 6130 cpi r22,lo8(1) + 2352 0104 7105 cpc r23,__zero_reg__ + 2353 0106 8105 cpc r24,__zero_reg__ + 2354 0108 9105 cpc r25,__zero_reg__ + 2355 010a 01F4 brne .L120 + 2356 .LVL226: + 2357 .L138: + 2358 010c 8C81 ldd r24,Y+4 + 2359 010e 8068 ori r24,lo8(-128) + 2360 0110 8C83 std Y+4,r24 + 2361 .L136: + 2362 0112 92E0 ldi r25,lo8(2) + 2363 0114 792E mov r7,r25 + 2364 0116 00C0 rjmp .L109 + 2365 .LVL227: + 2366 .L120: + 2367 .LSM186: + 2368 0118 6F3F cpi r22,lo8(-1) + 2369 011a FFEF ldi r31,hi8(-1) + 2370 011c 7F07 cpc r23,r31 + 2371 011e FFEF ldi r31,hlo8(-1) + 2372 0120 8F07 cpc r24,r31 + 2373 0122 FFEF ldi r31,hhi8(-1) + 2374 0124 9F07 cpc r25,r31 + 2375 0126 01F4 brne .+2 + 2376 0128 00C0 rjmp .L137 + 2377 .L121: + 2378 .LSM187: + 2379 012a 6A8B std Y+18,r22 + 2380 012c 7B8B std Y+19,r23 + 2381 012e 8C8B std Y+20,r24 + 2382 0130 9D8B std Y+21,r25 + 2383 .LSM188: + 2384 0132 1D82 std Y+5,__zero_reg__ + 2385 .L115: + 2386 .LSM189: + 2387 0134 E881 ld r30,Y + 2388 0136 F981 ldd r31,Y+1 + 2389 0138 22A5 ldd r18,Z+42 + 2390 013a 33A5 ldd r19,Z+43 + 2391 013c 44A5 ldd r20,Z+44 + 2392 013e 55A5 ldd r21,Z+45 + 2393 0140 8E89 ldd r24,Y+22 + 2394 0142 9F89 ldd r25,Y+23 + 2395 0144 A88D ldd r26,Y+24 + 2396 0146 B98D ldd r27,Y+25 + 2397 0148 2817 cp r18,r24 + 2398 014a 3907 cpc r19,r25 + 2399 014c 4A07 cpc r20,r26 + 2400 014e 5B07 cpc r21,r27 + 2401 0150 01F4 brne .L122 + 2402 0152 CF01 movw r24,r30 + 2403 0154 40E0 ldi r20,lo8(0) + 2404 0156 50E0 ldi r21,hi8(0) + 2405 0158 60E0 ldi r22,hlo8(0) + 2406 015a 70E0 ldi r23,hhi8(0) + 2407 015c 0E94 0000 call move_window + 2408 .LVL228: + 2409 0160 8823 tst r24 + 2410 0162 01F0 breq .+2 + 2411 0164 00C0 rjmp .L137 + 2412 .LVL229: + 2413 .L122: + 2414 .LSM190: + 2415 0166 0881 ld r16,Y + 2416 0168 1981 ldd r17,Y+1 + 2417 .LVL230: + 2418 016a 4A89 ldd r20,Y+18 + 2419 016c 5B89 ldd r21,Y+19 + 2420 016e 6C89 ldd r22,Y+20 + 2421 0170 7D89 ldd r23,Y+21 + 2422 0172 C801 movw r24,r16 + 2423 0174 0E94 0000 call clust2sect + 2424 .LVL231: + 2425 .LSM191: + 2426 0178 6115 cp r22,__zero_reg__ + 2427 017a 7105 cpc r23,__zero_reg__ + 2428 017c 8105 cpc r24,__zero_reg__ + 2429 017e 9105 cpc r25,__zero_reg__ + 2430 0180 01F0 breq .L138 + 2431 .LVL232: + 2432 .L123: + 2433 .LSM192: + 2434 0182 3D81 ldd r19,Y+5 + 2435 0184 5B01 movw r10,r22 + 2436 0186 6C01 movw r12,r24 + 2437 0188 A30E add r10,r19 + 2438 018a B11C adc r11,__zero_reg__ + 2439 018c C11C adc r12,__zero_reg__ + 2440 018e D11C adc r13,__zero_reg__ + 2441 .LVL233: + 2442 .LSM193: + 2443 0190 7401 movw r14,r8 + 2444 0192 EF2C mov r14,r15 + 2445 0194 FF24 clr r15 + 2446 0196 E694 lsr r14 + 2447 .LSM194: + 2448 0198 E114 cp r14,__zero_reg__ + 2449 019a F104 cpc r15,__zero_reg__ + 2450 019c 01F4 brne .+2 + 2451 019e 00C0 rjmp .L124 + 2452 .LSM195: + 2453 01a0 F801 movw r30,r16 + 2454 01a2 2281 ldd r18,Z+2 + 2455 01a4 432F mov r20,r19 + 2456 01a6 50E0 ldi r21,lo8(0) + 2457 01a8 C701 movw r24,r14 + 2458 01aa 840F add r24,r20 + 2459 01ac 951F adc r25,r21 + 2460 01ae 30E0 ldi r19,lo8(0) + 2461 01b0 2817 cp r18,r24 + 2462 01b2 3907 cpc r19,r25 + 2463 01b4 00F4 brsh .L125 + 2464 .LSM196: + 2465 01b6 7901 movw r14,r18 + 2466 01b8 E41A sub r14,r20 + 2467 01ba F50A sbc r15,r21 + 2468 .L125: + 2469 .LSM197: + 2470 01bc F801 movw r30,r16 + 2471 01be 8181 ldd r24,Z+1 + 2472 01c0 B201 movw r22,r4 + 2473 01c2 A601 movw r20,r12 + 2474 01c4 9501 movw r18,r10 + 2475 01c6 0E2D mov r16,r14 + 2476 01c8 0E94 0000 call disk_write + 2477 01cc 8823 tst r24 + 2478 01ce 01F0 breq .+2 + 2479 01d0 00C0 rjmp .L137 + 2480 .L126: + 2481 .LSM198: + 2482 01d2 E881 ld r30,Y + 2483 01d4 F981 ldd r31,Y+1 + 2484 01d6 22A5 ldd r18,Z+42 + 2485 01d8 33A5 ldd r19,Z+43 + 2486 01da 44A5 ldd r20,Z+44 + 2487 01dc 55A5 ldd r21,Z+45 + 2488 01de 2A19 sub r18,r10 + 2489 01e0 3B09 sbc r19,r11 + 2490 01e2 4C09 sbc r20,r12 + 2491 01e4 5D09 sbc r21,r13 + 2492 01e6 C701 movw r24,r14 + 2493 01e8 A0E0 ldi r26,lo8(0) + 2494 01ea B0E0 ldi r27,hi8(0) + 2495 .LVL234: + 2496 01ec 2817 cp r18,r24 + 2497 01ee 3907 cpc r19,r25 + 2498 01f0 4A07 cpc r20,r26 + 2499 01f2 5B07 cpc r21,r27 + 2500 01f4 00F4 brsh .L127 + 2501 .LVL235: + 2502 .LSM199: + 2503 01f6 19E0 ldi r17,9 + 2504 01f8 220F 1: lsl r18 + 2505 01fa 331F rol r19 + 2506 01fc 441F rol r20 + 2507 01fe 551F rol r21 + 2508 0200 1A95 dec r17 + 2509 0202 01F4 brne 1b + 2510 .LVL236: + 2511 0204 B201 movw r22,r4 + 2512 0206 620F add r22,r18 + 2513 0208 731F adc r23,r19 + 2514 020a CF01 movw r24,r30 + 2515 .LVL237: + 2516 020c 8E96 adiw r24,46 + 2517 020e 40E0 ldi r20,lo8(512) + 2518 0210 52E0 ldi r21,hi8(512) + 2519 0212 0E94 0000 call mem_cpy + 2520 .LVL238: + 2521 .LSM200: + 2522 0216 E881 ld r30,Y + 2523 0218 F981 ldd r31,Y+1 + 2524 021a 1482 std Z+4,__zero_reg__ + 2525 .LVL239: + 2526 .L127: + 2527 .LSM201: + 2528 021c 8D81 ldd r24,Y+5 + 2529 021e 8E0D add r24,r14 + 2530 0220 8D83 std Y+5,r24 + 2531 .LSM202: + 2532 0222 8701 movw r16,r14 + 2533 .LVL240: + 2534 0224 102F mov r17,r16 + 2535 0226 0027 clr r16 + 2536 0228 110F lsl r17 + 2537 022a 00C0 rjmp .L128 + 2538 .LVL241: + 2539 .L124: + 2540 .LSM203: + 2541 022c 2E81 ldd r18,Y+6 + 2542 022e 3F81 ldd r19,Y+7 + 2543 0230 4885 ldd r20,Y+8 + 2544 0232 5985 ldd r21,Y+9 + 2545 0234 8A85 ldd r24,Y+10 + 2546 0236 9B85 ldd r25,Y+11 + 2547 0238 AC85 ldd r26,Y+12 + 2548 023a BD85 ldd r27,Y+13 + 2549 023c 2817 cp r18,r24 + 2550 023e 3907 cpc r19,r25 + 2551 0240 4A07 cpc r20,r26 + 2552 0242 5B07 cpc r21,r27 + 2553 0244 00F0 brlo .L129 + 2554 .LSM204: + 2555 0246 C801 movw r24,r16 + 2556 0248 40E0 ldi r20,lo8(0) + 2557 024a 50E0 ldi r21,hi8(0) + 2558 024c 60E0 ldi r22,hlo8(0) + 2559 024e 70E0 ldi r23,hhi8(0) + 2560 0250 0E94 0000 call move_window + 2561 0254 8823 tst r24 + 2562 0256 01F4 brne .L137 + 2563 .L130: + 2564 .LSM205: + 2565 0258 E881 ld r30,Y + 2566 025a F981 ldd r31,Y+1 + 2567 025c A2A6 std Z+42,r10 + 2568 025e B3A6 std Z+43,r11 + 2569 0260 C4A6 std Z+44,r12 + 2570 0262 D5A6 std Z+45,r13 + 2571 .L129: + 2572 .LSM206: + 2573 0264 AE8A std Y+22,r10 + 2574 0266 BF8A std Y+23,r11 + 2575 0268 C88E std Y+24,r12 + 2576 026a D98E std Y+25,r13 + 2577 .LSM207: + 2578 026c 8D81 ldd r24,Y+5 + 2579 026e 8F5F subi r24,lo8(-(1)) + 2580 0270 8D83 std Y+5,r24 + 2581 .LVL242: + 2582 .L114: + 2583 .LSM208: + 2584 0272 EE80 ldd r14,Y+6 + 2585 0274 FF80 ldd r15,Y+7 + 2586 0276 0885 ldd r16,Y+8 + 2587 0278 1985 ldd r17,Y+9 + 2588 .LVL243: + 2589 .LSM209: + 2590 027a 4E89 ldd r20,Y+22 + 2591 027c 5F89 ldd r21,Y+23 + 2592 027e 688D ldd r22,Y+24 + 2593 0280 798D ldd r23,Y+25 + 2594 0282 8881 ld r24,Y + 2595 0284 9981 ldd r25,Y+1 + 2596 0286 0E94 0000 call move_window + 2597 .LVL244: + 2598 028a 8823 tst r24 + 2599 028c 01F0 breq .L131 + 2600 .LVL245: + 2601 .L137: + 2602 .LSM210: + 2603 028e 8C81 ldd r24,Y+4 + 2604 0290 8068 ori r24,lo8(-128) + 2605 0292 8C83 std Y+4,r24 + 2606 0294 7724 clr r7 + 2607 0296 7394 inc r7 + 2608 0298 00C0 rjmp .L109 + 2609 .LVL246: + 2610 .L131: + 2611 .LSM211: + 2612 029a C701 movw r24,r14 + 2613 029c 9170 andi r25,hi8(511) + 2614 029e 20E0 ldi r18,lo8(512) + 2615 02a0 32E0 ldi r19,hi8(512) + 2616 02a2 281B sub r18,r24 + 2617 02a4 390B sbc r19,r25 + 2618 02a6 8401 movw r16,r8 + 2619 .LVL247: + 2620 02a8 2815 cp r18,r8 + 2621 02aa 3905 cpc r19,r9 + 2622 02ac 00F4 brsh .L132 + 2623 .LVL248: + 2624 02ae 8901 movw r16,r18 + 2625 .L132: + 2626 .LSM212: + 2627 02b0 2E81 ldd r18,Y+6 + 2628 02b2 3F81 ldd r19,Y+7 + 2629 .LVL249: + 2630 02b4 3170 andi r19,hi8(511) + 2631 02b6 225D subi r18,lo8(-(46)) + 2632 02b8 3F4F sbci r19,hi8(-(46)) + 2633 02ba 8881 ld r24,Y + 2634 02bc 9981 ldd r25,Y+1 + 2635 02be 820F add r24,r18 + 2636 02c0 931F adc r25,r19 + 2637 02c2 B201 movw r22,r4 + 2638 02c4 A801 movw r20,r16 + 2639 02c6 0E94 0000 call mem_cpy + 2640 .LSM213: + 2641 02ca E881 ld r30,Y + 2642 02cc F981 ldd r31,Y+1 + 2643 02ce 6482 std Z+4,r6 + 2644 .LVL250: + 2645 .L128: + 2646 .LSM214: + 2647 02d0 400E add r4,r16 + 2648 02d2 511E adc r5,r17 + 2649 02d4 C801 movw r24,r16 + 2650 02d6 A0E0 ldi r26,lo8(0) + 2651 02d8 B0E0 ldi r27,hi8(0) + 2652 .LVL251: + 2653 02da 2E81 ldd r18,Y+6 + 2654 02dc 3F81 ldd r19,Y+7 + 2655 02de 4885 ldd r20,Y+8 + 2656 02e0 5985 ldd r21,Y+9 + 2657 02e2 280F add r18,r24 + 2658 02e4 391F adc r19,r25 + 2659 02e6 4A1F adc r20,r26 + 2660 02e8 5B1F adc r21,r27 + 2661 02ea 2E83 std Y+6,r18 + 2662 02ec 3F83 std Y+7,r19 + 2663 02ee 4887 std Y+8,r20 + 2664 02f0 5987 std Y+9,r21 + 2665 02f2 F101 movw r30,r2 + 2666 02f4 8081 ld r24,Z + 2667 02f6 9181 ldd r25,Z+1 + 2668 02f8 800F add r24,r16 + 2669 02fa 911F adc r25,r17 + 2670 02fc 9183 std Z+1,r25 + 2671 02fe 8083 st Z,r24 + 2672 0300 801A sub r8,r16 + 2673 0302 910A sbc r9,r17 + 2674 .LVL252: + 2675 .L113: + 2676 .LSM215: + 2677 0304 8114 cp r8,__zero_reg__ + 2678 0306 9104 cpc r9,__zero_reg__ + 2679 0308 01F0 breq .+2 + 2680 030a 00C0 rjmp .L133 + 2681 .LVL253: + 2682 .L119: + 2683 .LSM216: + 2684 030c 2E81 ldd r18,Y+6 + 2685 030e 3F81 ldd r19,Y+7 + 2686 0310 4885 ldd r20,Y+8 + 2687 0312 5985 ldd r21,Y+9 + 2688 0314 8A85 ldd r24,Y+10 + 2689 0316 9B85 ldd r25,Y+11 + 2690 0318 AC85 ldd r26,Y+12 + 2691 031a BD85 ldd r27,Y+13 + 2692 031c 8217 cp r24,r18 + 2693 031e 9307 cpc r25,r19 + 2694 0320 A407 cpc r26,r20 + 2695 0322 B507 cpc r27,r21 + 2696 0324 00F4 brsh .L134 + 2697 0326 2A87 std Y+10,r18 + 2698 0328 3B87 std Y+11,r19 + 2699 032a 4C87 std Y+12,r20 + 2700 032c 5D87 std Y+13,r21 + 2701 .L134: + 2702 .LSM217: + 2703 032e 8C81 ldd r24,Y+4 + 2704 0330 8062 ori r24,lo8(32) + 2705 0332 8C83 std Y+4,r24 + 2706 .LVL254: + 2707 .L109: + 2708 .LSM218: + 2709 0334 872D mov r24,r7 + 2710 /* epilogue start */ + 2711 0336 DF91 pop r29 + 2712 0338 CF91 pop r28 + 2713 .LVL255: + 2714 033a 1F91 pop r17 + 2715 .LVL256: + 2716 033c 0F91 pop r16 + 2717 .LVL257: + 2718 033e FF90 pop r15 + 2719 0340 EF90 pop r14 + 2720 .LVL258: + 2721 0342 DF90 pop r13 + 2722 0344 CF90 pop r12 + 2723 0346 BF90 pop r11 + 2724 0348 AF90 pop r10 + 2725 .LVL259: + 2726 034a 9F90 pop r9 + 2727 034c 8F90 pop r8 + 2728 .LVL260: + 2729 034e 7F90 pop r7 + 2730 .LVL261: + 2731 0350 6F90 pop r6 + 2732 0352 5F90 pop r5 + 2733 0354 4F90 pop r4 + 2734 .LVL262: + 2735 0356 3F90 pop r3 + 2736 0358 2F90 pop r2 + 2737 .LVL263: + 2738 035a 0895 ret + 2739 .LFE75: + 2741 .section .text.f_putc,"ax",@progbits + 2742 .global f_putc + 2744 f_putc: + 2745 .LFB80: + 2746 .LSM219: + 2747 .LVL264: + 2748 0000 0F93 push r16 + 2749 0002 1F93 push r17 + 2750 0004 DF93 push r29 + 2751 0006 CF93 push r28 + 2752 0008 00D0 rcall . + 2753 000a 0F92 push __tmp_reg__ + 2754 000c CDB7 in r28,__SP_L__ + 2755 000e DEB7 in r29,__SP_H__ + 2756 /* prologue: function */ + 2757 /* frame size = 3 */ + 2758 0010 8C01 movw r16,r24 + 2759 .LSM220: + 2760 0012 6115 cp r22,__zero_reg__ + 2761 0014 7105 cpc r23,__zero_reg__ + 2762 0016 01F0 breq .L140 + 2763 .LVL265: + 2764 .LSM221: + 2765 0018 8983 std Y+1,r24 + 2766 .LVL266: + 2767 .LSM222: + 2768 001a CB01 movw r24,r22 + 2769 001c BE01 movw r22,r28 + 2770 .LVL267: + 2771 001e 6F5F subi r22,lo8(-(1)) + 2772 0020 7F4F sbci r23,hi8(-(1)) + 2773 0022 41E0 ldi r20,lo8(1) + 2774 0024 50E0 ldi r21,hi8(1) + 2775 0026 9E01 movw r18,r28 + 2776 0028 2E5F subi r18,lo8(-(2)) + 2777 002a 3F4F sbci r19,hi8(-(2)) + 2778 002c 0E94 0000 call f_write + 2779 .LSM223: + 2780 0030 8A81 ldd r24,Y+2 + 2781 0032 9B81 ldd r25,Y+3 + 2782 .LVL268: + 2783 0034 892B or r24,r25 + 2784 0036 01F4 brne .L140 + 2785 .LVL269: + 2786 0038 0FEF ldi r16,lo8(-1) + 2787 003a 1FEF ldi r17,hi8(-1) + 2788 .LVL270: + 2789 .L140: + 2790 .LSM224: + 2791 003c C801 movw r24,r16 + 2792 .LVL271: + 2793 /* epilogue start */ + 2794 003e 0F90 pop __tmp_reg__ + 2795 0040 0F90 pop __tmp_reg__ + 2796 0042 0F90 pop __tmp_reg__ + 2797 0044 CF91 pop r28 + 2798 0046 DF91 pop r29 + 2799 0048 1F91 pop r17 + 2800 004a 0F91 pop r16 + 2801 004c 0895 ret + 2802 .LFE80: + 2804 .section .text.f_puts,"ax",@progbits + 2805 .global f_puts + 2807 f_puts: + 2808 .LFB81: + 2809 .LSM225: + 2810 .LVL272: + 2811 0000 EF92 push r14 + 2812 0002 FF92 push r15 + 2813 0004 0F93 push r16 + 2814 0006 1F93 push r17 + 2815 0008 CF93 push r28 + 2816 000a DF93 push r29 + 2817 /* prologue: function */ + 2818 /* frame size = 0 */ + 2819 000c 8C01 movw r16,r24 + 2820 000e 7B01 movw r14,r22 + 2821 .LSM226: + 2822 0010 C0E0 ldi r28,lo8(0) + 2823 0012 D0E0 ldi r29,hi8(0) + 2824 .LVL273: + 2825 0014 00C0 rjmp .L143 + 2826 .LVL274: + 2827 .L146: + 2828 .LSM227: + 2829 0016 90E0 ldi r25,lo8(0) + 2830 0018 B701 movw r22,r14 + 2831 001a 0E94 0000 call f_putc + 2832 001e 8F5F subi r24,lo8(-1) + 2833 0020 9F4F sbci r25,hi8(-1) + 2834 0022 01F4 brne .L144 + 2835 0024 CFEF ldi r28,lo8(-1) + 2836 0026 DFEF ldi r29,hi8(-1) + 2837 0028 00C0 rjmp .L145 + 2838 .L144: + 2839 .LSM228: + 2840 002a 0F5F subi r16,lo8(-(1)) + 2841 002c 1F4F sbci r17,hi8(-(1)) + 2842 002e 2196 adiw r28,1 + 2843 .LVL275: + 2844 .L143: + 2845 0030 F801 movw r30,r16 + 2846 0032 8081 ld r24,Z + 2847 0034 8823 tst r24 + 2848 0036 01F4 brne .L146 + 2849 .L145: + 2850 .LSM229: + 2851 0038 CE01 movw r24,r28 + 2852 .LVL276: + 2853 /* epilogue start */ + 2854 003a DF91 pop r29 + 2855 003c CF91 pop r28 + 2856 003e 1F91 pop r17 + 2857 0040 0F91 pop r16 + 2858 .LVL277: + 2859 0042 FF90 pop r15 + 2860 0044 EF90 pop r14 + 2861 .LVL278: + 2862 0046 0895 ret + 2863 .LFE81: + 2865 .section .text.f_printf,"ax",@progbits + 2866 .global f_printf + 2868 f_printf: + 2869 .LFB82: + 2870 .LSM230: + 2871 .LVL279: + 2872 0000 2F92 push r2 + 2873 0002 3F92 push r3 + 2874 0004 4F92 push r4 + 2875 0006 5F92 push r5 + 2876 0008 6F92 push r6 + 2877 000a 7F92 push r7 + 2878 000c 8F92 push r8 + 2879 000e 9F92 push r9 + 2880 0010 AF92 push r10 + 2881 0012 BF92 push r11 + 2882 0014 CF92 push r12 + 2883 0016 DF92 push r13 + 2884 0018 EF92 push r14 + 2885 001a FF92 push r15 + 2886 001c 0F93 push r16 + 2887 001e 1F93 push r17 + 2888 0020 DF93 push r29 + 2889 0022 CF93 push r28 + 2890 0024 CDB7 in r28,__SP_L__ + 2891 0026 DEB7 in r29,__SP_H__ + 2892 0028 6397 sbiw r28,19 + 2893 002a 0FB6 in __tmp_reg__,__SREG__ + 2894 002c F894 cli + 2895 002e DEBF out __SP_H__,r29 + 2896 0030 0FBE out __SREG__,__tmp_reg__ + 2897 0032 CDBF out __SP_L__,r28 + 2898 /* prologue: function */ + 2899 /* frame size = 19 */ + 2900 0034 6AA4 ldd r6,Y+42 + 2901 0036 7BA4 ldd r7,Y+43 + 2902 .LSM231: + 2903 0038 8E01 movw r16,r28 + 2904 .LVL280: + 2905 003a 045D subi r16,lo8(-(44)) + 2906 003c 1F4F sbci r17,hi8(-(44)) + 2907 003e 1A8A std Y+18,__zero_reg__ + 2908 0040 198A std Y+17,__zero_reg__ + 2909 .LVL281: + 2910 0042 20E0 ldi r18,lo8(0) + 2911 0044 30E0 ldi r19,hi8(0) + 2912 .LVL282: + 2913 .LVL283: + 2914 .L176: + 2915 .LSM232: + 2916 0046 D301 movw r26,r6 + 2917 0048 8C91 ld r24,X + 2918 .LVL284: + 2919 .LSM233: + 2920 004a 8823 tst r24 + 2921 004c 01F4 brne .+2 + 2922 004e 00C0 rjmp .L149 + 2923 .LSM234: + 2924 0050 0894 sec + 2925 0052 611C adc r6,__zero_reg__ + 2926 0054 711C adc r7,__zero_reg__ + 2927 .LSM235: + 2928 0056 8532 cpi r24,lo8(37) + 2929 0058 01F0 breq .L150 + 2930 .LSM236: + 2931 005a 90E0 ldi r25,lo8(0) + 2932 005c 68A5 ldd r22,Y+40 + 2933 005e 79A5 ldd r23,Y+41 + 2934 0060 0E94 0000 call f_putc + 2935 .LVL285: + 2936 0064 9C01 movw r18,r24 + 2937 .LVL286: + 2938 .LSM237: + 2939 0066 BFEF ldi r27,hi8(-1) + 2940 0068 8F3F cpi r24,lo8(-1) + 2941 006a 9B07 cpc r25,r27 + 2942 006c 01F4 brne .L151 + 2943 .LVL287: + 2944 006e 4801 movw r8,r16 + 2945 0070 00C0 rjmp .L152 + 2946 .L151: + 2947 0072 4801 movw r8,r16 + 2948 0074 00C0 rjmp .L179 + 2949 .LVL288: + 2950 .L150: + 2951 .LSM238: + 2952 0076 D301 movw r26,r6 + 2953 0078 ED91 ld r30,X+ + 2954 .LVL289: + 2955 007a 3D01 movw r6,r26 + 2956 .LSM239: + 2957 007c E033 cpi r30,lo8(48) + 2958 007e 01F0 breq .L153 + 2959 0080 1B8A std Y+19,__zero_reg__ + 2960 .LVL290: + 2961 0082 00C0 rjmp .L154 + 2962 .L153: + 2963 .LSM240: + 2964 0084 ED91 ld r30,X+ + 2965 0086 3D01 movw r6,r26 + 2966 0088 B1E0 ldi r27,lo8(1) + 2967 008a BB8B std Y+19,r27 + 2968 .LVL291: + 2969 .L154: + 2970 008c AA24 clr r10 + 2971 008e BB24 clr r11 + 2972 0090 00C0 rjmp .L155 + 2973 .L156: + 2974 .LSM241: + 2975 0092 C501 movw r24,r10 + 2976 0094 F3E0 ldi r31,3 + 2977 0096 880F 1: lsl r24 + 2978 0098 991F rol r25 + 2979 009a FA95 dec r31 + 2980 009c 01F4 brne 1b + 2981 009e AA0C lsl r10 + 2982 00a0 BB1C rol r11 + 2983 00a2 A80E add r10,r24 + 2984 00a4 B91E adc r11,r25 + 2985 00a6 AE0E add r10,r30 + 2986 00a8 B11C adc r11,__zero_reg__ + 2987 00aa E0ED ldi r30,lo8(-48) + 2988 00ac FFEF ldi r31,hi8(-48) + 2989 .LVL292: + 2990 00ae AE0E add r10,r30 + 2991 00b0 BF1E adc r11,r31 + 2992 .LSM242: + 2993 00b2 D301 movw r26,r6 + 2994 00b4 ED91 ld r30,X+ + 2995 .LVL293: + 2996 00b6 3D01 movw r6,r26 + 2997 .L155: + 2998 .LSM243: + 2999 00b8 8E2F mov r24,r30 + 3000 00ba 8053 subi r24,lo8(-(-48)) + 3001 00bc 8A30 cpi r24,lo8(10) + 3002 00be 00F0 brlo .L156 + 3003 .LSM244: + 3004 00c0 EC36 cpi r30,lo8(108) + 3005 00c2 01F4 brne .L157 + 3006 .LSM245: + 3007 00c4 BB89 ldd r27,Y+19 + 3008 00c6 B260 ori r27,lo8(2) + 3009 00c8 BB8B std Y+19,r27 + 3010 .LVL294: + 3011 00ca D301 movw r26,r6 + 3012 00cc ED91 ld r30,X+ + 3013 00ce 3D01 movw r6,r26 + 3014 .L157: + 3015 .LSM246: + 3016 00d0 E337 cpi r30,lo8(115) + 3017 00d2 01F4 brne .L158 + 3018 .LSM247: + 3019 00d4 62E0 ldi r22,lo8(2) + 3020 00d6 862E mov r8,r22 + 3021 00d8 912C mov r9,__zero_reg__ + 3022 .LVL295: + 3023 00da 800E add r8,r16 + 3024 00dc 911E adc r9,r17 + 3025 00de F801 movw r30,r16 + 3026 .LVL296: + 3027 00e0 8081 ld r24,Z + 3028 00e2 9181 ldd r25,Z+1 + 3029 00e4 00C0 rjmp .L180 + 3030 .LVL297: + 3031 .L158: + 3032 .LSM248: + 3033 00e6 E336 cpi r30,lo8(99) + 3034 00e8 01F4 brne .L159 + 3035 .LSM249: + 3036 00ea 52E0 ldi r21,lo8(2) + 3037 00ec 852E mov r8,r21 + 3038 00ee 912C mov r9,__zero_reg__ + 3039 .LVL298: + 3040 00f0 800E add r8,r16 + 3041 00f2 911E adc r9,r17 + 3042 00f4 D801 movw r26,r16 + 3043 00f6 8D91 ld r24,X+ + 3044 00f8 9C91 ld r25,X + 3045 00fa 68A5 ldd r22,Y+40 + 3046 00fc 79A5 ldd r23,Y+41 + 3047 00fe 0E94 0000 call f_putc + 3048 .LVL299: + 3049 0102 9C01 movw r18,r24 + 3050 .LVL300: + 3051 .LSM250: + 3052 0104 BFEF ldi r27,hi8(-1) + 3053 0106 8F3F cpi r24,lo8(-1) + 3054 0108 9B07 cpc r25,r27 + 3055 010a 01F4 brne .+2 + 3056 010c 00C0 rjmp .L152 + 3057 .LVL301: + 3058 .L179: + 3059 010e 21E0 ldi r18,lo8(1) + 3060 0110 30E0 ldi r19,hi8(1) + 3061 .LVL302: + 3062 0112 00C0 rjmp .L152 + 3063 .LVL303: + 3064 .L159: + 3065 .LSM251: + 3066 0114 E436 cpi r30,lo8(100) + 3067 0116 01F0 breq .L160 + 3068 .LSM252: + 3069 0118 E537 cpi r30,lo8(117) + 3070 011a 01F0 breq .L160 + 3071 .LSM253: + 3072 011c E835 cpi r30,lo8(88) + 3073 011e 01F0 breq .+2 + 3074 0120 00C0 rjmp .L149 + 3075 0122 20E1 ldi r18,lo8(16) + 3076 .LVL304: + 3077 0124 00C0 rjmp .L161 + 3078 .LVL305: + 3079 .L160: + 3080 0126 2AE0 ldi r18,lo8(10) + 3081 .LVL306: + 3082 .L161: + 3083 .LSM254: + 3084 0128 FB89 ldd r31,Y+19 + 3085 012a F1FF sbrs r31,1 + 3086 012c 00C0 rjmp .L162 + 3087 .LSM255: + 3088 012e 44E0 ldi r20,lo8(4) + 3089 0130 842E mov r8,r20 + 3090 0132 912C mov r9,__zero_reg__ + 3091 .LVL307: + 3092 0134 800E add r8,r16 + 3093 0136 911E adc r9,r17 + 3094 0138 D801 movw r26,r16 + 3095 013a ED90 ld r14,X+ + 3096 013c FD90 ld r15,X+ + 3097 013e 0D91 ld r16,X+ + 3098 0140 1C91 ld r17,X + 3099 .LSM256: + 3100 0142 E436 cpi r30,lo8(100) + 3101 0144 01F4 brne .L164 + 3102 .LVL308: + 3103 0146 00C0 rjmp .L163 + 3104 .L162: + 3105 0148 C801 movw r24,r16 + 3106 014a 0296 adiw r24,2 + 3107 .LVL309: + 3108 014c D801 movw r26,r16 + 3109 014e 6D91 ld r22,X+ + 3110 0150 7C91 ld r23,X + 3111 .LSM257: + 3112 0152 E436 cpi r30,lo8(100) + 3113 0154 01F4 brne .L165 + 3114 .LVL310: + 3115 0156 4C01 movw r8,r24 + 3116 0158 7B01 movw r14,r22 + 3117 015a 0027 clr r16 + 3118 015c F7FC sbrc r15,7 + 3119 015e 0095 com r16 + 3120 0160 102F mov r17,r16 + 3121 0162 00C0 rjmp .L163 + 3122 .LVL311: + 3123 .L165: + 3124 0164 4C01 movw r8,r24 + 3125 0166 7B01 movw r14,r22 + 3126 .LVL312: + 3127 0168 00E0 ldi r16,lo8(0) + 3128 016a 10E0 ldi r17,hi8(0) + 3129 .LVL313: + 3130 016c 00C0 rjmp .L164 + 3131 .LVL314: + 3132 .L163: + 3133 .LSM258: + 3134 016e 17FF sbrs r17,7 + 3135 0170 00C0 rjmp .L164 + 3136 .LSM259: + 3137 0172 1095 com r17 + 3138 0174 0095 com r16 + 3139 0176 F094 com r15 + 3140 0178 E094 com r14 + 3141 017a E11C adc r14,__zero_reg__ + 3142 017c F11C adc r15,__zero_reg__ + 3143 017e 011D adc r16,__zero_reg__ + 3144 0180 111D adc r17,__zero_reg__ + 3145 .LSM260: + 3146 0182 BB89 ldd r27,Y+19 + 3147 0184 B460 ori r27,lo8(4) + 3148 0186 BB8B std Y+19,r27 + 3149 .LVL315: + 3150 .L164: + 3151 .LSM261: + 3152 0188 188A std Y+16,__zero_reg__ + 3153 018a 3FE0 ldi r19,lo8(15) + 3154 018c C32E mov r12,r19 + 3155 018e D12C mov r13,__zero_reg__ + 3156 .LSM262: + 3157 0190 222E mov r2,r18 + 3158 0192 3324 clr r3 + 3159 0194 4424 clr r4 + 3160 0196 5524 clr r5 + 3161 .LVL316: + 3162 .L169: + 3163 0198 C801 movw r24,r16 + 3164 019a B701 movw r22,r14 + 3165 019c A201 movw r20,r4 + 3166 019e 9101 movw r18,r2 + 3167 .LVL317: + 3168 01a0 0E94 0000 call __udivmodsi4 + 3169 .LVL318: + 3170 01a4 862F mov r24,r22 + 3171 .LVL319: + 3172 01a6 805D subi r24,lo8(-(48)) + 3173 .LSM263: + 3174 01a8 8A33 cpi r24,lo8(58) + 3175 01aa 00F0 brlo .L166 + 3176 01ac 895F subi r24,lo8(-(7)) + 3177 .L166: + 3178 .LSM264: + 3179 01ae 0894 sec + 3180 01b0 C108 sbc r12,__zero_reg__ + 3181 01b2 D108 sbc r13,__zero_reg__ + 3182 01b4 E1E0 ldi r30,lo8(1) + 3183 01b6 F0E0 ldi r31,hi8(1) + 3184 01b8 EC0F add r30,r28 + 3185 01ba FD1F adc r31,r29 + 3186 01bc EC0D add r30,r12 + 3187 01be FD1D adc r31,r13 + 3188 01c0 8083 st Z,r24 + 3189 .LSM265: + 3190 01c2 C114 cp r12,__zero_reg__ + 3191 01c4 D104 cpc r13,__zero_reg__ + 3192 01c6 01F0 breq .L168 + 3193 .LSM266: + 3194 01c8 C801 movw r24,r16 + 3195 01ca B701 movw r22,r14 + 3196 01cc A201 movw r20,r4 + 3197 01ce 9101 movw r18,r2 + 3198 01d0 0E94 0000 call __udivmodsi4 + 3199 01d4 C901 movw r24,r18 + 3200 .LVL320: + 3201 01d6 DA01 movw r26,r20 + 3202 01d8 7C01 movw r14,r24 + 3203 01da 8D01 movw r16,r26 + 3204 .LSM267: + 3205 01dc E114 cp r14,__zero_reg__ + 3206 01de F104 cpc r15,__zero_reg__ + 3207 01e0 0105 cpc r16,__zero_reg__ + 3208 01e2 1105 cpc r17,__zero_reg__ + 3209 01e4 01F4 brne .L169 + 3210 .LSM268: + 3211 01e6 EB89 ldd r30,Y+19 + 3212 01e8 E2FF sbrs r30,2 + 3213 01ea 00C0 rjmp .L168 + 3214 01ec 0894 sec + 3215 01ee C108 sbc r12,__zero_reg__ + 3216 01f0 D108 sbc r13,__zero_reg__ + 3217 01f2 E1E0 ldi r30,lo8(1) + 3218 01f4 F0E0 ldi r31,hi8(1) + 3219 01f6 EC0F add r30,r28 + 3220 01f8 FD1F adc r31,r29 + 3221 01fa EC0D add r30,r12 + 3222 01fc FD1D adc r31,r13 + 3223 01fe 4DE2 ldi r20,lo8(45) + 3224 0200 4083 st Z,r20 + 3225 .LVL321: + 3226 .L168: + 3227 .LSM269: + 3228 0202 8FE0 ldi r24,lo8(15) + 3229 0204 90E0 ldi r25,hi8(15) + 3230 .LVL322: + 3231 0206 8A19 sub r24,r10 + 3232 0208 9B09 sbc r25,r11 + 3233 020a 0894 sec + 3234 020c C108 sbc r12,__zero_reg__ + 3235 020e D108 sbc r13,__zero_reg__ + 3236 0210 E1E0 ldi r30,lo8(1) + 3237 0212 F0E0 ldi r31,hi8(1) + 3238 0214 EC0F add r30,r28 + 3239 0216 FD1F adc r31,r29 + 3240 0218 EC0D add r30,r12 + 3241 021a FD1D adc r31,r13 + 3242 021c 0894 sec + 3243 021e C11C adc r12,__zero_reg__ + 3244 0220 D11C adc r13,__zero_reg__ + 3245 .LSM270: + 3246 0222 AB89 ldd r26,Y+19 + 3247 0224 2A2F mov r18,r26 + 3248 0226 30E0 ldi r19,lo8(0) + 3249 0228 2170 andi r18,lo8(1) + 3250 022a 3070 andi r19,hi8(1) + 3251 022c 00C0 rjmp .L170 + 3252 .L174: + 3253 022e 0894 sec + 3254 0230 C108 sbc r12,__zero_reg__ + 3255 0232 D108 sbc r13,__zero_reg__ + 3256 0234 2115 cp r18,__zero_reg__ + 3257 0236 3105 cpc r19,__zero_reg__ + 3258 0238 01F4 brne .L171 + 3259 023a 40E2 ldi r20,lo8(32) + 3260 023c 00C0 rjmp .L172 + 3261 .L171: + 3262 023e 40E3 ldi r20,lo8(48) + 3263 .L172: + 3264 0240 4083 st Z,r20 + 3265 0242 3197 sbiw r30,1 + 3266 .L170: + 3267 0244 C114 cp r12,__zero_reg__ + 3268 0246 D104 cpc r13,__zero_reg__ + 3269 0248 01F0 breq .L173 + 3270 024a 8C15 cp r24,r12 + 3271 024c 9D05 cpc r25,r13 + 3272 024e 04F0 brlt .L174 + 3273 .L173: + 3274 .LSM271: + 3275 0250 81E0 ldi r24,lo8(1) + 3276 0252 90E0 ldi r25,hi8(1) + 3277 .LVL323: + 3278 0254 8C0F add r24,r28 + 3279 0256 9D1F adc r25,r29 + 3280 0258 8C0D add r24,r12 + 3281 025a 9D1D adc r25,r13 + 3282 .LVL324: + 3283 .L180: + 3284 025c 68A5 ldd r22,Y+40 + 3285 025e 79A5 ldd r23,Y+41 + 3286 0260 0E94 0000 call f_puts + 3287 .LVL325: + 3288 0264 9C01 movw r18,r24 + 3289 .LVL326: + 3290 .L152: + 3291 .LSM272: + 3292 0266 E989 ldd r30,Y+17 + 3293 0268 FA89 ldd r31,Y+18 + 3294 026a E20F add r30,r18 + 3295 026c F31F adc r31,r19 + 3296 026e FA8B std Y+18,r31 + 3297 0270 E98B std Y+17,r30 + 3298 .LVL327: + 3299 0272 FFEF ldi r31,hi8(-1) + 3300 0274 2F3F cpi r18,lo8(-1) + 3301 0276 3F07 cpc r19,r31 + 3302 0278 01F0 breq .L175 + 3303 027a 8401 movw r16,r8 + 3304 .LVL328: + 3305 027c 00C0 rjmp .L176 + 3306 .LVL329: + 3307 .L149: + 3308 .LSM273: + 3309 027e 4FEF ldi r20,hi8(-1) + 3310 0280 2F3F cpi r18,lo8(-1) + 3311 0282 3407 cpc r19,r20 + 3312 0284 01F0 breq .L175 + 3313 0286 2989 ldd r18,Y+17 + 3314 0288 3A89 ldd r19,Y+18 + 3315 .LVL330: + 3316 .L175: + 3317 .LSM274: + 3318 028a C901 movw r24,r18 + 3319 .LVL331: + 3320 /* epilogue start */ + 3321 028c 6396 adiw r28,19 + 3322 028e 0FB6 in __tmp_reg__,__SREG__ + 3323 0290 F894 cli + 3324 0292 DEBF out __SP_H__,r29 + 3325 0294 0FBE out __SREG__,__tmp_reg__ + 3326 0296 CDBF out __SP_L__,r28 + 3327 0298 CF91 pop r28 + 3328 029a DF91 pop r29 + 3329 029c 1F91 pop r17 + 3330 029e 0F91 pop r16 + 3331 .LVL332: + 3332 02a0 FF90 pop r15 + 3333 02a2 EF90 pop r14 + 3334 .LVL333: + 3335 02a4 DF90 pop r13 + 3336 02a6 CF90 pop r12 + 3337 .LVL334: + 3338 02a8 BF90 pop r11 + 3339 02aa AF90 pop r10 + 3340 .LVL335: + 3341 02ac 9F90 pop r9 + 3342 02ae 8F90 pop r8 + 3343 .LVL336: + 3344 02b0 7F90 pop r7 + 3345 02b2 6F90 pop r6 + 3346 .LVL337: + 3347 02b4 5F90 pop r5 + 3348 02b6 4F90 pop r4 + 3349 02b8 3F90 pop r3 + 3350 02ba 2F90 pop r2 + 3351 02bc 0895 ret + 3352 .LFE82: + 3354 .section .text.dir_next,"ax",@progbits + 3356 dir_next: + 3357 .LFB64: + 3358 .LSM275: + 3359 .LVL338: + 3360 0000 8F92 push r8 + 3361 0002 9F92 push r9 + 3362 0004 AF92 push r10 + 3363 0006 BF92 push r11 + 3364 0008 CF92 push r12 + 3365 000a DF92 push r13 + 3366 000c EF92 push r14 + 3367 000e FF92 push r15 + 3368 0010 0F93 push r16 + 3369 0012 1F93 push r17 + 3370 0014 CF93 push r28 + 3371 0016 DF93 push r29 + 3372 /* prologue: function */ + 3373 /* frame size = 0 */ + 3374 0018 EC01 movw r28,r24 + 3375 001a 162F mov r17,r22 + 3376 .LSM276: + 3377 001c AC80 ldd r10,Y+4 + 3378 001e BD80 ldd r11,Y+5 + 3379 .LVL339: + 3380 0020 0894 sec + 3381 0022 A11C adc r10,__zero_reg__ + 3382 0024 B11C adc r11,__zero_reg__ + 3383 .LSM277: + 3384 0026 A114 cp r10,__zero_reg__ + 3385 0028 B104 cpc r11,__zero_reg__ + 3386 002a 01F4 brne .+2 + 3387 002c 00C0 rjmp .L182 + 3388 .LVL340: + 3389 002e 8E85 ldd r24,Y+14 + 3390 0030 9F85 ldd r25,Y+15 + 3391 0032 A889 ldd r26,Y+16 + 3392 0034 B989 ldd r27,Y+17 + 3393 0036 0097 sbiw r24,0 + 3394 0038 A105 cpc r26,__zero_reg__ + 3395 003a B105 cpc r27,__zero_reg__ + 3396 003c 01F4 brne .+2 + 3397 003e 00C0 rjmp .L182 + 3398 .LSM278: + 3399 0040 0FE0 ldi r16,lo8(15) + 3400 0042 802E mov r8,r16 + 3401 0044 912C mov r9,__zero_reg__ + 3402 0046 8A20 and r8,r10 + 3403 0048 9B20 and r9,r11 + 3404 004a 8114 cp r8,__zero_reg__ + 3405 004c 9104 cpc r9,__zero_reg__ + 3406 004e 01F0 breq .+2 + 3407 0050 00C0 rjmp .L183 + 3408 .LSM279: + 3409 0052 0196 adiw r24,1 + 3410 0054 A11D adc r26,__zero_reg__ + 3411 0056 B11D adc r27,__zero_reg__ + 3412 0058 8E87 std Y+14,r24 + 3413 005a 9F87 std Y+15,r25 + 3414 005c A88B std Y+16,r26 + 3415 005e B98B std Y+17,r27 + 3416 .LSM280: + 3417 0060 4A85 ldd r20,Y+10 + 3418 0062 5B85 ldd r21,Y+11 + 3419 0064 6C85 ldd r22,Y+12 + 3420 0066 7D85 ldd r23,Y+13 + 3421 0068 E881 ld r30,Y + 3422 006a F981 ldd r31,Y+1 + 3423 006c 4115 cp r20,__zero_reg__ + 3424 006e 5105 cpc r21,__zero_reg__ + 3425 0070 6105 cpc r22,__zero_reg__ + 3426 0072 7105 cpc r23,__zero_reg__ + 3427 0074 01F4 brne .L184 + 3428 .LSM281: + 3429 0076 8085 ldd r24,Z+8 + 3430 0078 9185 ldd r25,Z+9 + 3431 007a A816 cp r10,r24 + 3432 007c B906 cpc r11,r25 + 3433 007e 00F4 brsh .+2 + 3434 0080 00C0 rjmp .L183 + 3435 0082 00C0 rjmp .L182 + 3436 .L184: + 3437 .LSM282: + 3438 0084 8281 ldd r24,Z+2 + 3439 0086 90E0 ldi r25,lo8(0) + 3440 0088 0197 sbiw r24,1 + 3441 008a 9501 movw r18,r10 + 3442 008c B4E0 ldi r27,4 + 3443 008e 3695 1: lsr r19 + 3444 0090 2795 ror r18 + 3445 0092 BA95 dec r27 + 3446 0094 01F4 brne 1b + 3447 0096 8223 and r24,r18 + 3448 0098 9323 and r25,r19 + 3449 009a 892B or r24,r25 + 3450 009c 01F0 breq .+2 + 3451 009e 00C0 rjmp .L183 + 3452 .LSM283: + 3453 00a0 CF01 movw r24,r30 + 3454 00a2 0E94 0000 call get_fat + 3455 00a6 6B01 movw r12,r22 + 3456 00a8 7C01 movw r14,r24 + 3457 .LVL341: + 3458 .LSM284: + 3459 00aa 82E0 ldi r24,lo8(2) + 3460 00ac C816 cp r12,r24 + 3461 00ae D104 cpc r13,__zero_reg__ + 3462 00b0 E104 cpc r14,__zero_reg__ + 3463 00b2 F104 cpc r15,__zero_reg__ + 3464 00b4 00F4 brsh .+2 + 3465 00b6 00C0 rjmp .L185 + 3466 .LSM285: + 3467 00b8 9FEF ldi r25,lo8(-1) + 3468 00ba C916 cp r12,r25 + 3469 00bc 9FEF ldi r25,hi8(-1) + 3470 00be D906 cpc r13,r25 + 3471 00c0 9FEF ldi r25,hlo8(-1) + 3472 00c2 E906 cpc r14,r25 + 3473 00c4 9FEF ldi r25,hhi8(-1) + 3474 00c6 F906 cpc r15,r25 + 3475 00c8 01F4 brne .+2 + 3476 00ca 00C0 rjmp .L186 + 3477 .LSM286: + 3478 00cc E881 ld r30,Y + 3479 00ce F981 ldd r31,Y+1 + 3480 00d0 828D ldd r24,Z+26 + 3481 00d2 938D ldd r25,Z+27 + 3482 00d4 A48D ldd r26,Z+28 + 3483 00d6 B58D ldd r27,Z+29 + 3484 00d8 C816 cp r12,r24 + 3485 00da D906 cpc r13,r25 + 3486 00dc EA06 cpc r14,r26 + 3487 00de FB06 cpc r15,r27 + 3488 00e0 00F4 brsh .+2 + 3489 00e2 00C0 rjmp .L187 + 3490 .LBB3: + 3491 .LSM287: + 3492 00e4 1123 tst r17 + 3493 00e6 01F4 brne .+2 + 3494 00e8 00C0 rjmp .L182 + 3495 .LSM288: + 3496 00ea 4A85 ldd r20,Y+10 + 3497 00ec 5B85 ldd r21,Y+11 + 3498 00ee 6C85 ldd r22,Y+12 + 3499 00f0 7D85 ldd r23,Y+13 + 3500 00f2 CF01 movw r24,r30 + 3501 00f4 0E94 0000 call create_chain + 3502 00f8 6B01 movw r12,r22 + 3503 00fa 7C01 movw r14,r24 + 3504 .LSM289: + 3505 00fc 6115 cp r22,__zero_reg__ + 3506 00fe 7105 cpc r23,__zero_reg__ + 3507 0100 8105 cpc r24,__zero_reg__ + 3508 0102 9105 cpc r25,__zero_reg__ + 3509 0104 01F4 brne .L188 + 3510 .LVL342: + 3511 0106 87E0 ldi r24,lo8(7) + 3512 0108 00C0 rjmp .L189 + 3513 .L188: + 3514 .LSM290: + 3515 010a 6130 cpi r22,lo8(1) + 3516 010c 7105 cpc r23,__zero_reg__ + 3517 010e 8105 cpc r24,__zero_reg__ + 3518 0110 9105 cpc r25,__zero_reg__ + 3519 0112 01F4 brne .+2 + 3520 0114 00C0 rjmp .L185 + 3521 .LSM291: + 3522 0116 6F3F cpi r22,lo8(-1) + 3523 0118 FFEF ldi r31,hi8(-1) + 3524 011a 7F07 cpc r23,r31 + 3525 011c FFEF ldi r31,hlo8(-1) + 3526 011e 8F07 cpc r24,r31 + 3527 0120 FFEF ldi r31,hhi8(-1) + 3528 0122 9F07 cpc r25,r31 + 3529 0124 01F4 brne .+2 + 3530 0126 00C0 rjmp .L186 + 3531 .LSM292: + 3532 0128 8881 ld r24,Y + 3533 012a 9981 ldd r25,Y+1 + 3534 012c 40E0 ldi r20,lo8(0) + 3535 012e 50E0 ldi r21,hi8(0) + 3536 0130 60E0 ldi r22,hlo8(0) + 3537 0132 70E0 ldi r23,hhi8(0) + 3538 0134 0E94 0000 call move_window + 3539 .LVL343: + 3540 0138 8823 tst r24 + 3541 013a 01F0 breq .+2 + 3542 013c 00C0 rjmp .L186 + 3543 .LSM293: + 3544 013e 8881 ld r24,Y + 3545 0140 9981 ldd r25,Y+1 + 3546 0142 8E96 adiw r24,46 + 3547 0144 60E0 ldi r22,lo8(0) + 3548 0146 70E0 ldi r23,hi8(0) + 3549 0148 40E0 ldi r20,lo8(512) + 3550 014a 52E0 ldi r21,hi8(512) + 3551 014c 0E94 0000 call mem_set + 3552 .LSM294: + 3553 0150 0881 ld r16,Y + 3554 0152 1981 ldd r17,Y+1 + 3555 0154 C801 movw r24,r16 + 3556 0156 B701 movw r22,r14 + 3557 0158 A601 movw r20,r12 + 3558 015a 0E94 0000 call clust2sect + 3559 015e F801 movw r30,r16 + 3560 0160 62A7 std Z+42,r22 + 3561 0162 73A7 std Z+43,r23 + 3562 0164 84A7 std Z+44,r24 + 3563 0166 95A7 std Z+45,r25 + 3564 0168 00E0 ldi r16,lo8(0) + 3565 .LVL344: + 3566 .LSM295: + 3567 016a 11E0 ldi r17,lo8(1) + 3568 .LVL345: + 3569 016c 00C0 rjmp .L190 + 3570 .L191: + 3571 016e 1483 std Z+4,r17 + 3572 .LSM296: + 3573 0170 8881 ld r24,Y + 3574 0172 9981 ldd r25,Y+1 + 3575 0174 40E0 ldi r20,lo8(0) + 3576 0176 50E0 ldi r21,hi8(0) + 3577 0178 60E0 ldi r22,hlo8(0) + 3578 017a 70E0 ldi r23,hhi8(0) + 3579 017c 0E94 0000 call move_window + 3580 0180 8823 tst r24 + 3581 0182 01F0 breq .+2 + 3582 0184 00C0 rjmp .L186 + 3583 .LSM297: + 3584 0186 E881 ld r30,Y + 3585 0188 F981 ldd r31,Y+1 + 3586 018a 82A5 ldd r24,Z+42 + 3587 018c 93A5 ldd r25,Z+43 + 3588 018e A4A5 ldd r26,Z+44 + 3589 0190 B5A5 ldd r27,Z+45 + 3590 0192 0196 adiw r24,1 + 3591 0194 A11D adc r26,__zero_reg__ + 3592 0196 B11D adc r27,__zero_reg__ + 3593 0198 82A7 std Z+42,r24 + 3594 019a 93A7 std Z+43,r25 + 3595 019c A4A7 std Z+44,r26 + 3596 019e B5A7 std Z+45,r27 + 3597 .LSM298: + 3598 01a0 0F5F subi r16,lo8(-(1)) + 3599 .L190: + 3600 01a2 E881 ld r30,Y + 3601 01a4 F981 ldd r31,Y+1 + 3602 01a6 8281 ldd r24,Z+2 + 3603 01a8 0817 cp r16,r24 + 3604 01aa 00F0 brlo .L191 + 3605 .LSM299: + 3606 01ac 82A5 ldd r24,Z+42 + 3607 01ae 93A5 ldd r25,Z+43 + 3608 01b0 A4A5 ldd r26,Z+44 + 3609 01b2 B5A5 ldd r27,Z+45 + 3610 01b4 801B sub r24,r16 + 3611 01b6 9109 sbc r25,__zero_reg__ + 3612 01b8 A109 sbc r26,__zero_reg__ + 3613 01ba B109 sbc r27,__zero_reg__ + 3614 01bc 82A7 std Z+42,r24 + 3615 01be 93A7 std Z+43,r25 + 3616 01c0 A4A7 std Z+44,r26 + 3617 01c2 B5A7 std Z+45,r27 + 3618 .LVL346: + 3619 .L187: + 3620 .LBE3: + 3621 .LSM300: + 3622 01c4 CA86 std Y+10,r12 + 3623 01c6 DB86 std Y+11,r13 + 3624 01c8 EC86 std Y+12,r14 + 3625 01ca FD86 std Y+13,r15 + 3626 .LSM301: + 3627 01cc 8881 ld r24,Y + 3628 01ce 9981 ldd r25,Y+1 + 3629 01d0 B701 movw r22,r14 + 3630 01d2 A601 movw r20,r12 + 3631 01d4 0E94 0000 call clust2sect + 3632 01d8 6E87 std Y+14,r22 + 3633 01da 7F87 std Y+15,r23 + 3634 01dc 888B std Y+16,r24 + 3635 01de 998B std Y+17,r25 + 3636 .LVL347: + 3637 .L183: + 3638 .LSM302: + 3639 01e0 BD82 std Y+5,r11 + 3640 01e2 AC82 std Y+4,r10 + 3641 .LSM303: + 3642 01e4 A5E0 ldi r26,5 + 3643 01e6 880C 1: lsl r8 + 3644 01e8 991C rol r9 + 3645 01ea AA95 dec r26 + 3646 01ec 01F4 brne 1b + 3647 01ee 8EE2 ldi r24,lo8(46) + 3648 01f0 90E0 ldi r25,hi8(46) + 3649 01f2 880E add r8,r24 + 3650 01f4 991E adc r9,r25 + 3651 01f6 8881 ld r24,Y + 3652 01f8 9981 ldd r25,Y+1 + 3653 01fa 880D add r24,r8 + 3654 01fc 991D adc r25,r9 + 3655 01fe 9B8B std Y+19,r25 + 3656 0200 8A8B std Y+18,r24 + 3657 0202 80E0 ldi r24,lo8(0) + 3658 0204 00C0 rjmp .L189 + 3659 .LVL348: + 3660 .L182: + 3661 .LSM304: + 3662 0206 84E0 ldi r24,lo8(4) + 3663 0208 00C0 rjmp .L189 + 3664 .LVL349: + 3665 .L185: + 3666 020a 82E0 ldi r24,lo8(2) + 3667 020c 00C0 rjmp .L189 + 3668 .LVL350: + 3669 .L186: + 3670 020e 81E0 ldi r24,lo8(1) + 3671 .LVL351: + 3672 .L189: + 3673 /* epilogue start */ + 3674 .LSM305: + 3675 0210 DF91 pop r29 + 3676 0212 CF91 pop r28 + 3677 .LVL352: + 3678 0214 1F91 pop r17 + 3679 .LVL353: + 3680 0216 0F91 pop r16 + 3681 .LVL354: + 3682 0218 FF90 pop r15 + 3683 021a EF90 pop r14 + 3684 021c DF90 pop r13 + 3685 021e CF90 pop r12 + 3686 .LVL355: + 3687 0220 BF90 pop r11 + 3688 0222 AF90 pop r10 + 3689 .LVL356: + 3690 0224 9F90 pop r9 + 3691 0226 8F90 pop r8 + 3692 0228 0895 ret + 3693 .LFE64: + 3695 .section .text.f_read,"ax",@progbits + 3696 .global f_read + 3698 f_read: + 3699 .LFB74: + 3700 .LSM306: + 3701 .LVL357: + 3702 0000 2F92 push r2 + 3703 0002 3F92 push r3 + 3704 0004 5F92 push r5 + 3705 0006 6F92 push r6 + 3706 0008 7F92 push r7 + 3707 000a 8F92 push r8 + 3708 000c 9F92 push r9 + 3709 000e AF92 push r10 + 3710 0010 BF92 push r11 + 3711 0012 CF92 push r12 + 3712 0014 DF92 push r13 + 3713 0016 EF92 push r14 + 3714 0018 FF92 push r15 + 3715 001a 0F93 push r16 + 3716 001c 1F93 push r17 + 3717 001e CF93 push r28 + 3718 0020 DF93 push r29 + 3719 /* prologue: function */ + 3720 /* frame size = 0 */ + 3721 0022 EC01 movw r28,r24 + 3722 0024 162F mov r17,r22 + 3723 0026 072F mov r16,r23 + 3724 .LVL358: + 3725 0028 4A01 movw r8,r20 + 3726 002a 1901 movw r2,r18 + 3727 .LSM307: + 3728 002c F901 movw r30,r18 + 3729 002e 1182 std Z+1,__zero_reg__ + 3730 0030 1082 st Z,__zero_reg__ + 3731 .LSM308: + 3732 0032 6A81 ldd r22,Y+2 + 3733 0034 7B81 ldd r23,Y+3 + 3734 .LVL359: + 3735 0036 8881 ld r24,Y + 3736 0038 9981 ldd r25,Y+1 + 3737 .LVL360: + 3738 003a 0E94 0000 call validate + 3739 .LVL361: + 3740 003e 582E mov r5,r24 + 3741 .LVL362: + 3742 .LSM309: + 3743 0040 8823 tst r24 + 3744 0042 01F0 breq .+2 + 3745 0044 00C0 rjmp .L194 + 3746 .LVL363: + 3747 .LSM310: + 3748 0046 8C81 ldd r24,Y+4 + 3749 .LVL364: + 3750 0048 87FD sbrc r24,7 + 3751 004a 00C0 rjmp .L215 + 3752 .L195: + 3753 .LSM311: + 3754 004c 80FD sbrc r24,0 + 3755 004e 00C0 rjmp .L196 + 3756 0050 47E0 ldi r20,lo8(7) + 3757 0052 542E mov r5,r20 + 3758 0054 00C0 rjmp .L194 + 3759 .L196: + 3760 .LSM312: + 3761 0056 2A85 ldd r18,Y+10 + 3762 0058 3B85 ldd r19,Y+11 + 3763 005a 4C85 ldd r20,Y+12 + 3764 005c 5D85 ldd r21,Y+13 + 3765 .LVL365: + 3766 005e 8E81 ldd r24,Y+6 + 3767 0060 9F81 ldd r25,Y+7 + 3768 0062 A885 ldd r26,Y+8 + 3769 0064 B985 ldd r27,Y+9 + 3770 0066 281B sub r18,r24 + 3771 0068 390B sbc r19,r25 + 3772 006a 4A0B sbc r20,r26 + 3773 006c 5B0B sbc r21,r27 + 3774 .LSM313: + 3775 006e C401 movw r24,r8 + 3776 0070 A0E0 ldi r26,lo8(0) + 3777 0072 B0E0 ldi r27,hi8(0) + 3778 .LVL366: + 3779 0074 2817 cp r18,r24 + 3780 0076 3907 cpc r19,r25 + 3781 0078 4A07 cpc r20,r26 + 3782 007a 5B07 cpc r21,r27 + 3783 007c 00F4 brsh .L197 + 3784 .LVL367: + 3785 007e 4901 movw r8,r18 + 3786 .LVL368: + 3787 .L197: + 3788 .LSM314: + 3789 0080 812F mov r24,r17 + 3790 .LVL369: + 3791 0082 902F mov r25,r16 + 3792 .LVL370: + 3793 0084 9C01 movw r18,r24 + 3794 .LVL371: + 3795 0086 3901 movw r6,r18 + 3796 .LVL372: + 3797 0088 00C0 rjmp .L198 + 3798 .LVL373: + 3799 .L213: + 3800 .LSM315: + 3801 008a 2E81 ldd r18,Y+6 + 3802 008c 3F81 ldd r19,Y+7 + 3803 008e 4885 ldd r20,Y+8 + 3804 0090 5985 ldd r21,Y+9 + 3805 0092 DA01 movw r26,r20 + 3806 0094 C901 movw r24,r18 + 3807 0096 9170 andi r25,hi8(511) + 3808 0098 A070 andi r26,hlo8(511) + 3809 009a B070 andi r27,hhi8(511) + 3810 009c 0097 sbiw r24,0 + 3811 009e A105 cpc r26,__zero_reg__ + 3812 00a0 B105 cpc r27,__zero_reg__ + 3813 00a2 01F0 breq .+2 + 3814 00a4 00C0 rjmp .L199 + 3815 .LSM316: + 3816 00a6 E881 ld r30,Y + 3817 00a8 F981 ldd r31,Y+1 + 3818 00aa 9D81 ldd r25,Y+5 + 3819 .LVL374: + 3820 00ac 8281 ldd r24,Z+2 + 3821 00ae 9817 cp r25,r24 + 3822 00b0 00F0 brlo .L200 + 3823 .LSM317: + 3824 00b2 2115 cp r18,__zero_reg__ + 3825 00b4 3105 cpc r19,__zero_reg__ + 3826 00b6 4105 cpc r20,__zero_reg__ + 3827 00b8 5105 cpc r21,__zero_reg__ + 3828 00ba 01F4 brne .L201 + 3829 00bc 6E85 ldd r22,Y+14 + 3830 00be 7F85 ldd r23,Y+15 + 3831 00c0 8889 ldd r24,Y+16 + 3832 00c2 9989 ldd r25,Y+17 + 3833 .LVL375: + 3834 00c4 00C0 rjmp .L202 + 3835 .LVL376: + 3836 .L201: + 3837 00c6 4A89 ldd r20,Y+18 + 3838 00c8 5B89 ldd r21,Y+19 + 3839 00ca 6C89 ldd r22,Y+20 + 3840 00cc 7D89 ldd r23,Y+21 + 3841 00ce CF01 movw r24,r30 + 3842 00d0 0E94 0000 call get_fat + 3843 .LVL377: + 3844 .L202: + 3845 .LSM318: + 3846 00d4 6230 cpi r22,lo8(2) + 3847 00d6 7105 cpc r23,__zero_reg__ + 3848 00d8 8105 cpc r24,__zero_reg__ + 3849 00da 9105 cpc r25,__zero_reg__ + 3850 00dc 00F4 brsh .L203 + 3851 .LVL378: + 3852 .L217: + 3853 00de 8C81 ldd r24,Y+4 + 3854 00e0 8068 ori r24,lo8(-128) + 3855 00e2 8C83 std Y+4,r24 + 3856 .L215: + 3857 00e4 32E0 ldi r19,lo8(2) + 3858 00e6 532E mov r5,r19 + 3859 00e8 00C0 rjmp .L194 + 3860 .LVL379: + 3861 .L203: + 3862 .LSM319: + 3863 00ea 6F3F cpi r22,lo8(-1) + 3864 00ec FFEF ldi r31,hi8(-1) + 3865 00ee 7F07 cpc r23,r31 + 3866 00f0 FFEF ldi r31,hlo8(-1) + 3867 00f2 8F07 cpc r24,r31 + 3868 00f4 FFEF ldi r31,hhi8(-1) + 3869 00f6 9F07 cpc r25,r31 + 3870 00f8 01F4 brne .+2 + 3871 00fa 00C0 rjmp .L216 + 3872 .L204: + 3873 .LSM320: + 3874 00fc 6A8B std Y+18,r22 + 3875 00fe 7B8B std Y+19,r23 + 3876 0100 8C8B std Y+20,r24 + 3877 0102 9D8B std Y+21,r25 + 3878 .LSM321: + 3879 0104 1D82 std Y+5,__zero_reg__ + 3880 .L200: + 3881 .LSM322: + 3882 0106 0881 ld r16,Y + 3883 0108 1981 ldd r17,Y+1 + 3884 .LVL380: + 3885 010a 4A89 ldd r20,Y+18 + 3886 010c 5B89 ldd r21,Y+19 + 3887 010e 6C89 ldd r22,Y+20 + 3888 0110 7D89 ldd r23,Y+21 + 3889 0112 C801 movw r24,r16 + 3890 0114 0E94 0000 call clust2sect + 3891 .LVL381: + 3892 .LSM323: + 3893 0118 6115 cp r22,__zero_reg__ + 3894 011a 7105 cpc r23,__zero_reg__ + 3895 011c 8105 cpc r24,__zero_reg__ + 3896 011e 9105 cpc r25,__zero_reg__ + 3897 0120 01F0 breq .L217 + 3898 .LVL382: + 3899 .L205: + 3900 .LSM324: + 3901 0122 3D81 ldd r19,Y+5 + 3902 0124 5B01 movw r10,r22 + 3903 0126 6C01 movw r12,r24 + 3904 0128 A30E add r10,r19 + 3905 012a B11C adc r11,__zero_reg__ + 3906 012c C11C adc r12,__zero_reg__ + 3907 012e D11C adc r13,__zero_reg__ + 3908 .LVL383: + 3909 .LSM325: + 3910 0130 7401 movw r14,r8 + 3911 0132 EF2C mov r14,r15 + 3912 0134 FF24 clr r15 + 3913 0136 E694 lsr r14 + 3914 .LSM326: + 3915 0138 E114 cp r14,__zero_reg__ + 3916 013a F104 cpc r15,__zero_reg__ + 3917 013c 01F4 brne .+2 + 3918 013e 00C0 rjmp .L206 + 3919 .LSM327: + 3920 0140 F801 movw r30,r16 + 3921 0142 2281 ldd r18,Z+2 + 3922 0144 432F mov r20,r19 + 3923 0146 50E0 ldi r21,lo8(0) + 3924 0148 C701 movw r24,r14 + 3925 014a 840F add r24,r20 + 3926 014c 951F adc r25,r21 + 3927 014e 30E0 ldi r19,lo8(0) + 3928 0150 2817 cp r18,r24 + 3929 0152 3907 cpc r19,r25 + 3930 0154 00F4 brsh .L207 + 3931 .LSM328: + 3932 0156 7901 movw r14,r18 + 3933 0158 E41A sub r14,r20 + 3934 015a F50A sbc r15,r21 + 3935 .L207: + 3936 .LSM329: + 3937 015c F801 movw r30,r16 + 3938 015e 8181 ldd r24,Z+1 + 3939 0160 B301 movw r22,r6 + 3940 0162 A601 movw r20,r12 + 3941 0164 9501 movw r18,r10 + 3942 0166 0E2D mov r16,r14 + 3943 0168 0E94 0000 call disk_read + 3944 016c 8823 tst r24 + 3945 016e 01F0 breq .+2 + 3946 0170 00C0 rjmp .L216 + 3947 .L208: + 3948 .LSM330: + 3949 0172 E881 ld r30,Y + 3950 0174 F981 ldd r31,Y+1 + 3951 0176 8481 ldd r24,Z+4 + 3952 0178 8823 tst r24 + 3953 017a 01F0 breq .L209 + 3954 017c 22A5 ldd r18,Z+42 + 3955 017e 33A5 ldd r19,Z+43 + 3956 0180 44A5 ldd r20,Z+44 + 3957 0182 55A5 ldd r21,Z+45 + 3958 0184 2A19 sub r18,r10 + 3959 0186 3B09 sbc r19,r11 + 3960 0188 4C09 sbc r20,r12 + 3961 018a 5D09 sbc r21,r13 + 3962 018c C701 movw r24,r14 + 3963 018e A0E0 ldi r26,lo8(0) + 3964 0190 B0E0 ldi r27,hi8(0) + 3965 .LVL384: + 3966 0192 2817 cp r18,r24 + 3967 0194 3907 cpc r19,r25 + 3968 0196 4A07 cpc r20,r26 + 3969 0198 5B07 cpc r21,r27 + 3970 019a 00F4 brsh .L209 + 3971 .LVL385: + 3972 .LSM331: + 3973 019c 99E0 ldi r25,9 + 3974 019e 220F 1: lsl r18 + 3975 01a0 331F rol r19 + 3976 01a2 441F rol r20 + 3977 01a4 551F rol r21 + 3978 01a6 9A95 dec r25 + 3979 01a8 01F4 brne 1b + 3980 01aa C301 movw r24,r6 + 3981 .LVL386: + 3982 01ac 820F add r24,r18 + 3983 01ae 931F adc r25,r19 + 3984 01b0 BE96 adiw r30,46 + 3985 01b2 BF01 movw r22,r30 + 3986 01b4 40E0 ldi r20,lo8(512) + 3987 01b6 52E0 ldi r21,hi8(512) + 3988 01b8 0E94 0000 call mem_cpy + 3989 .LVL387: + 3990 .L209: + 3991 .LSM332: + 3992 01bc 8D81 ldd r24,Y+5 + 3993 01be 8E0D add r24,r14 + 3994 01c0 8D83 std Y+5,r24 + 3995 .LSM333: + 3996 01c2 8701 movw r16,r14 + 3997 .LVL388: + 3998 01c4 102F mov r17,r16 + 3999 01c6 0027 clr r16 + 4000 01c8 110F lsl r17 + 4001 01ca 00C0 rjmp .L210 + 4002 .LVL389: + 4003 .L206: + 4004 .LSM334: + 4005 01cc AE8A std Y+22,r10 + 4006 01ce BF8A std Y+23,r11 + 4007 01d0 C88E std Y+24,r12 + 4008 01d2 D98E std Y+25,r13 + 4009 .LSM335: + 4010 01d4 3F5F subi r19,lo8(-(1)) + 4011 01d6 3D83 std Y+5,r19 + 4012 .LVL390: + 4013 .L199: + 4014 .LSM336: + 4015 01d8 EE80 ldd r14,Y+6 + 4016 01da FF80 ldd r15,Y+7 + 4017 01dc 0885 ldd r16,Y+8 + 4018 01de 1985 ldd r17,Y+9 + 4019 .LVL391: + 4020 .LSM337: + 4021 01e0 4E89 ldd r20,Y+22 + 4022 01e2 5F89 ldd r21,Y+23 + 4023 01e4 688D ldd r22,Y+24 + 4024 01e6 798D ldd r23,Y+25 + 4025 01e8 8881 ld r24,Y + 4026 01ea 9981 ldd r25,Y+1 + 4027 01ec 0E94 0000 call move_window + 4028 .LVL392: + 4029 01f0 8823 tst r24 + 4030 01f2 01F0 breq .L211 + 4031 .LVL393: + 4032 .L216: + 4033 .LSM338: + 4034 01f4 8C81 ldd r24,Y+4 + 4035 01f6 8068 ori r24,lo8(-128) + 4036 01f8 8C83 std Y+4,r24 + 4037 01fa 5524 clr r5 + 4038 01fc 5394 inc r5 + 4039 01fe 00C0 rjmp .L194 + 4040 .LVL394: + 4041 .L211: + 4042 .LSM339: + 4043 0200 C701 movw r24,r14 + 4044 0202 9170 andi r25,hi8(511) + 4045 0204 20E0 ldi r18,lo8(512) + 4046 0206 32E0 ldi r19,hi8(512) + 4047 0208 281B sub r18,r24 + 4048 020a 390B sbc r19,r25 + 4049 020c 8401 movw r16,r8 + 4050 .LVL395: + 4051 020e 2815 cp r18,r8 + 4052 0210 3905 cpc r19,r9 + 4053 0212 00F4 brsh .L212 + 4054 .LVL396: + 4055 0214 8901 movw r16,r18 + 4056 .L212: + 4057 .LSM340: + 4058 0216 8E81 ldd r24,Y+6 + 4059 0218 9F81 ldd r25,Y+7 + 4060 021a 9170 andi r25,hi8(511) + 4061 021c 8E96 adiw r24,46 + 4062 021e 6881 ld r22,Y + 4063 0220 7981 ldd r23,Y+1 + 4064 0222 680F add r22,r24 + 4065 0224 791F adc r23,r25 + 4066 0226 C301 movw r24,r6 + 4067 0228 A801 movw r20,r16 + 4068 022a 0E94 0000 call mem_cpy + 4069 .LVL397: + 4070 .L210: + 4071 .LSM341: + 4072 022e 600E add r6,r16 + 4073 0230 711E adc r7,r17 + 4074 0232 C801 movw r24,r16 + 4075 0234 A0E0 ldi r26,lo8(0) + 4076 0236 B0E0 ldi r27,hi8(0) + 4077 .LVL398: + 4078 0238 2E81 ldd r18,Y+6 + 4079 023a 3F81 ldd r19,Y+7 + 4080 023c 4885 ldd r20,Y+8 + 4081 023e 5985 ldd r21,Y+9 + 4082 0240 280F add r18,r24 + 4083 0242 391F adc r19,r25 + 4084 0244 4A1F adc r20,r26 + 4085 0246 5B1F adc r21,r27 + 4086 0248 2E83 std Y+6,r18 + 4087 024a 3F83 std Y+7,r19 + 4088 024c 4887 std Y+8,r20 + 4089 024e 5987 std Y+9,r21 + 4090 0250 F101 movw r30,r2 + 4091 0252 8081 ld r24,Z + 4092 0254 9181 ldd r25,Z+1 + 4093 0256 800F add r24,r16 + 4094 0258 911F adc r25,r17 + 4095 025a 9183 std Z+1,r25 + 4096 025c 8083 st Z,r24 + 4097 025e 801A sub r8,r16 + 4098 0260 910A sbc r9,r17 + 4099 .LVL399: + 4100 .L198: + 4101 .LSM342: + 4102 0262 8114 cp r8,__zero_reg__ + 4103 0264 9104 cpc r9,__zero_reg__ + 4104 0266 01F0 breq .+2 + 4105 0268 00C0 rjmp .L213 + 4106 .LVL400: + 4107 .L194: + 4108 .LSM343: + 4109 026a 852D mov r24,r5 + 4110 /* epilogue start */ + 4111 026c DF91 pop r29 + 4112 026e CF91 pop r28 + 4113 .LVL401: + 4114 0270 1F91 pop r17 + 4115 .LVL402: + 4116 0272 0F91 pop r16 + 4117 .LVL403: + 4118 0274 FF90 pop r15 + 4119 0276 EF90 pop r14 + 4120 .LVL404: + 4121 0278 DF90 pop r13 + 4122 027a CF90 pop r12 + 4123 027c BF90 pop r11 + 4124 027e AF90 pop r10 + 4125 .LVL405: + 4126 0280 9F90 pop r9 + 4127 0282 8F90 pop r8 + 4128 .LVL406: + 4129 0284 7F90 pop r7 + 4130 0286 6F90 pop r6 + 4131 .LVL407: + 4132 0288 5F90 pop r5 + 4133 .LVL408: + 4134 028a 3F90 pop r3 + 4135 028c 2F90 pop r2 + 4136 .LVL409: + 4137 028e 0895 ret + 4138 .LFE74: + 4140 .section .text.f_gets,"ax",@progbits + 4141 .global f_gets + 4143 f_gets: + 4144 .LFB79: + 4145 .LSM344: + 4146 .LVL410: + 4147 0000 6F92 push r6 + 4148 0002 7F92 push r7 + 4149 0004 8F92 push r8 + 4150 0006 9F92 push r9 + 4151 0008 AF92 push r10 + 4152 000a BF92 push r11 + 4153 000c CF92 push r12 + 4154 000e DF92 push r13 + 4155 0010 EF92 push r14 + 4156 0012 FF92 push r15 + 4157 0014 0F93 push r16 + 4158 0016 1F93 push r17 + 4159 0018 DF93 push r29 + 4160 001a CF93 push r28 + 4161 001c 00D0 rcall . + 4162 001e CDB7 in r28,__SP_L__ + 4163 0020 DEB7 in r29,__SP_H__ + 4164 /* prologue: function */ + 4165 /* frame size = 2 */ + 4166 0022 5C01 movw r10,r24 + 4167 0024 6B01 movw r12,r22 + 4168 0026 4A01 movw r8,r20 + 4169 .LSM345: + 4170 0028 8C01 movw r16,r24 + 4171 .LVL411: + 4172 002a EE24 clr r14 + 4173 002c FF24 clr r15 + 4174 .LVL412: + 4175 .LSM346: + 4176 002e 0894 sec + 4177 0030 C108 sbc r12,__zero_reg__ + 4178 0032 D108 sbc r13,__zero_reg__ + 4179 .LSM347: + 4180 0034 3E01 movw r6,r28 + 4181 0036 0894 sec + 4182 0038 611C adc r6,__zero_reg__ + 4183 003a 711C adc r7,__zero_reg__ + 4184 003c 00C0 rjmp .L219 + 4185 .LVL413: + 4186 .L221: + 4187 003e C401 movw r24,r8 + 4188 0040 B801 movw r22,r16 + 4189 .LVL414: + 4190 0042 41E0 ldi r20,lo8(1) + 4191 0044 50E0 ldi r21,hi8(1) + 4192 0046 9301 movw r18,r6 + 4193 0048 0E94 0000 call f_read + 4194 .LSM348: + 4195 004c 8981 ldd r24,Y+1 + 4196 004e 9A81 ldd r25,Y+2 + 4197 0050 0197 sbiw r24,1 + 4198 0052 01F4 brne .L220 + 4199 .LVL415: + 4200 .LSM349: + 4201 0054 0894 sec + 4202 0056 E11C adc r14,__zero_reg__ + 4203 0058 F11C adc r15,__zero_reg__ + 4204 .LSM350: + 4205 005a F801 movw r30,r16 + 4206 005c 8191 ld r24,Z+ + 4207 .LVL416: + 4208 005e 8F01 movw r16,r30 + 4209 0060 8A30 cpi r24,lo8(10) + 4210 0062 01F0 breq .L220 + 4211 .LVL417: + 4212 .L219: + 4213 .LSM351: + 4214 0064 EC14 cp r14,r12 + 4215 0066 FD04 cpc r15,r13 + 4216 0068 04F0 brlt .L221 + 4217 .LVL418: + 4218 .L220: + 4219 .LSM352: + 4220 006a F801 movw r30,r16 + 4221 006c 1082 st Z,__zero_reg__ + 4222 .LSM353: + 4223 006e EF28 or r14,r15 + 4224 0070 01F4 brne .L222 + 4225 0072 AA24 clr r10 + 4226 0074 BB24 clr r11 + 4227 .LVL419: + 4228 .L222: + 4229 .LSM354: + 4230 0076 C501 movw r24,r10 + 4231 .LVL420: + 4232 /* epilogue start */ + 4233 0078 0F90 pop __tmp_reg__ + 4234 007a 0F90 pop __tmp_reg__ + 4235 007c CF91 pop r28 + 4236 007e DF91 pop r29 + 4237 0080 1F91 pop r17 + 4238 0082 0F91 pop r16 + 4239 .LVL421: + 4240 0084 FF90 pop r15 + 4241 0086 EF90 pop r14 + 4242 .LVL422: + 4243 0088 DF90 pop r13 + 4244 008a CF90 pop r12 + 4245 008c BF90 pop r11 + 4246 008e AF90 pop r10 + 4247 0090 9F90 pop r9 + 4248 0092 8F90 pop r8 + 4249 .LVL423: + 4250 0094 7F90 pop r7 + 4251 0096 6F90 pop r6 + 4252 0098 0895 ret + 4253 .LFE79: + 4255 .section .text.check_fs,"ax",@progbits + 4257 check_fs: + 4258 .LFB69: + 4259 .LSM355: + 4260 .LVL424: + 4261 0000 0F93 push r16 + 4262 0002 CF93 push r28 + 4263 0004 DF93 push r29 + 4264 /* prologue: function */ + 4265 /* frame size = 0 */ + 4266 0006 EC01 movw r28,r24 + 4267 0008 9A01 movw r18,r20 + 4268 000a AB01 movw r20,r22 + 4269 .LSM356: + 4270 000c BC01 movw r22,r24 + 4271 000e 625D subi r22,lo8(-(46)) + 4272 0010 7F4F sbci r23,hi8(-(46)) + 4273 0012 8981 ldd r24,Y+1 + 4274 .LVL425: + 4275 0014 01E0 ldi r16,lo8(1) + 4276 0016 0E94 0000 call disk_read + 4277 .LVL426: + 4278 001a 8823 tst r24 + 4279 001c 01F0 breq .L225 + 4280 001e 63E0 ldi r22,lo8(3) + 4281 0020 00C0 rjmp .L226 + 4282 .L225: + 4283 .LSM357: + 4284 0022 C35D subi r28,lo8(-(557)) + 4285 0024 DD4F sbci r29,hi8(-(557)) + 4286 0026 9881 ld r25,Y + 4287 0028 80E0 ldi r24,lo8(0) + 4288 002a 2A91 ld r18,-Y + 4289 002c CC52 subi r28,lo8(-(-556)) + 4290 002e D240 sbci r29,hi8(-(-556)) + 4291 0030 30E0 ldi r19,lo8(0) + 4292 0032 822B or r24,r18 + 4293 0034 932B or r25,r19 + 4294 0036 8555 subi r24,lo8(-21931) + 4295 0038 9A4A sbci r25,hi8(-21931) + 4296 003a 01F0 breq .L227 + 4297 003c 62E0 ldi r22,lo8(2) + 4298 003e 00C0 rjmp .L226 + 4299 .L227: + 4300 .LSM358: + 4301 0040 C959 subi r28,lo8(-(103)) + 4302 0042 DF4F sbci r29,hi8(-(103)) + 4303 0044 2881 ld r18,Y + 4304 0046 30E0 ldi r19,lo8(0) + 4305 0048 40E0 ldi r20,lo8(0) + 4306 004a 50E0 ldi r21,hi8(0) + 4307 004c 522F mov r21,r18 + 4308 004e 4427 clr r20 + 4309 0050 3327 clr r19 + 4310 0052 2227 clr r18 + 4311 0054 8A91 ld r24,-Y + 4312 0056 90E0 ldi r25,lo8(0) + 4313 0058 A0E0 ldi r26,lo8(0) + 4314 005a B0E0 ldi r27,hi8(0) + 4315 005c DC01 movw r26,r24 + 4316 005e 9927 clr r25 + 4317 0060 8827 clr r24 + 4318 0062 282B or r18,r24 + 4319 0064 392B or r19,r25 + 4320 0066 4A2B or r20,r26 + 4321 0068 5B2B or r21,r27 + 4322 006a 2297 sbiw r28,2 + 4323 006c 8991 ld r24,Y+ + 4324 006e 90E0 ldi r25,lo8(0) + 4325 0070 A0E0 ldi r26,lo8(0) + 4326 0072 B0E0 ldi r27,hi8(0) + 4327 0074 282B or r18,r24 + 4328 0076 392B or r19,r25 + 4329 0078 4A2B or r20,r26 + 4330 007a 5B2B or r21,r27 + 4331 007c 9881 ld r25,Y + 4332 007e C556 subi r28,lo8(-(-101)) + 4333 0080 D040 sbci r29,hi8(-(-101)) + 4334 0082 80E0 ldi r24,lo8(0) + 4335 0084 A0E0 ldi r26,lo8(0) + 4336 0086 B0E0 ldi r27,hi8(0) + 4337 0088 282B or r18,r24 + 4338 008a 392B or r19,r25 + 4339 008c 4A2B or r20,r26 + 4340 008e 5B2B or r21,r27 + 4341 0090 5070 andi r21,hhi8(16777215) + 4342 0092 2654 subi r18,lo8(5521734) + 4343 0094 3144 sbci r19,hi8(5521734) + 4344 0096 4445 sbci r20,hlo8(5521734) + 4345 0098 5040 sbci r21,hhi8(5521734) + 4346 009a 01F4 brne .L228 + 4347 009c 60E0 ldi r22,lo8(0) + 4348 009e 00C0 rjmp .L226 + 4349 .L228: + 4350 00a0 60E0 ldi r22,lo8(0) + 4351 00a2 CD57 subi r28,lo8(-(131)) + 4352 00a4 DF4F sbci r29,hi8(-(131)) + 4353 00a6 2881 ld r18,Y + 4354 00a8 30E0 ldi r19,lo8(0) + 4355 00aa 40E0 ldi r20,lo8(0) + 4356 00ac 50E0 ldi r21,hi8(0) + 4357 00ae 522F mov r21,r18 + 4358 00b0 4427 clr r20 + 4359 00b2 3327 clr r19 + 4360 00b4 2227 clr r18 + 4361 00b6 8A91 ld r24,-Y + 4362 00b8 90E0 ldi r25,lo8(0) + 4363 00ba A0E0 ldi r26,lo8(0) + 4364 00bc B0E0 ldi r27,hi8(0) + 4365 00be DC01 movw r26,r24 + 4366 00c0 9927 clr r25 + 4367 00c2 8827 clr r24 + 4368 00c4 282B or r18,r24 + 4369 00c6 392B or r19,r25 + 4370 00c8 4A2B or r20,r26 + 4371 00ca 5B2B or r21,r27 + 4372 00cc 2297 sbiw r28,2 + 4373 00ce 8991 ld r24,Y+ + 4374 00d0 90E0 ldi r25,lo8(0) + 4375 00d2 A0E0 ldi r26,lo8(0) + 4376 00d4 B0E0 ldi r27,hi8(0) + 4377 00d6 282B or r18,r24 + 4378 00d8 392B or r19,r25 + 4379 00da 4A2B or r20,r26 + 4380 00dc 5B2B or r21,r27 + 4381 00de 9881 ld r25,Y + 4382 .LVL427: + 4383 00e0 80E0 ldi r24,lo8(0) + 4384 00e2 A0E0 ldi r26,lo8(0) + 4385 00e4 B0E0 ldi r27,hi8(0) + 4386 00e6 282B or r18,r24 + 4387 00e8 392B or r19,r25 + 4388 00ea 4A2B or r20,r26 + 4389 00ec 5B2B or r21,r27 + 4390 00ee 5070 andi r21,hhi8(16777215) + 4391 00f0 2654 subi r18,lo8(5521734) + 4392 00f2 3144 sbci r19,hi8(5521734) + 4393 00f4 4445 sbci r20,hlo8(5521734) + 4394 00f6 5040 sbci r21,hhi8(5521734) + 4395 00f8 01F0 breq .L226 + 4396 00fa 61E0 ldi r22,lo8(1) + 4397 .LVL428: + 4398 .L226: + 4399 .LSM359: + 4400 00fc 862F mov r24,r22 + 4401 /* epilogue start */ + 4402 00fe DF91 pop r29 + 4403 0100 CF91 pop r28 + 4404 .LVL429: + 4405 0102 0F91 pop r16 + 4406 0104 0895 ret + 4407 .LFE69: + 4409 .section .text.f_sync,"ax",@progbits + 4410 .global f_sync + 4412 f_sync: + 4413 .LFB76: + 4414 .LSM360: + 4415 .LVL430: + 4416 0000 0F93 push r16 + 4417 0002 1F93 push r17 + 4418 0004 CF93 push r28 + 4419 0006 DF93 push r29 + 4420 /* prologue: function */ + 4421 /* frame size = 0 */ + 4422 0008 EC01 movw r28,r24 + 4423 .LSM361: + 4424 000a 6A81 ldd r22,Y+2 + 4425 000c 7B81 ldd r23,Y+3 + 4426 000e 8881 ld r24,Y + 4427 0010 9981 ldd r25,Y+1 + 4428 .LVL431: + 4429 0012 0E94 0000 call validate + 4430 0016 982F mov r25,r24 + 4431 .LVL432: + 4432 .LSM362: + 4433 0018 8823 tst r24 + 4434 001a 01F0 breq .+2 + 4435 001c 00C0 rjmp .L232 + 4436 .LVL433: + 4437 .LSM363: + 4438 001e 8C81 ldd r24,Y+4 + 4439 .LVL434: + 4440 0020 85FF sbrs r24,5 + 4441 0022 00C0 rjmp .L232 + 4442 .LSM364: + 4443 0024 4A8D ldd r20,Y+26 + 4444 0026 5B8D ldd r21,Y+27 + 4445 0028 6C8D ldd r22,Y+28 + 4446 002a 7D8D ldd r23,Y+29 + 4447 002c 8881 ld r24,Y + 4448 002e 9981 ldd r25,Y+1 + 4449 0030 0E94 0000 call move_window + 4450 .LVL435: + 4451 0034 982F mov r25,r24 + 4452 .LVL436: + 4453 .LSM365: + 4454 0036 8823 tst r24 + 4455 0038 01F0 breq .+2 + 4456 003a 00C0 rjmp .L232 + 4457 .LVL437: + 4458 .LSM366: + 4459 003c 0E8D ldd r16,Y+30 + 4460 003e 1F8D ldd r17,Y+31 + 4461 .LVL438: + 4462 .LSM367: + 4463 0040 F801 movw r30,r16 + 4464 0042 8385 ldd r24,Z+11 + 4465 .LVL439: + 4466 0044 8062 ori r24,lo8(32) + 4467 0046 8387 std Z+11,r24 + 4468 .LSM368: + 4469 0048 8A85 ldd r24,Y+10 + 4470 004a 848F std Z+28,r24 + 4471 004c 8B85 ldd r24,Y+11 + 4472 004e 858F std Z+29,r24 + 4473 0050 8A85 ldd r24,Y+10 + 4474 0052 9B85 ldd r25,Y+11 + 4475 0054 AC85 ldd r26,Y+12 + 4476 0056 BD85 ldd r27,Y+13 + 4477 0058 CD01 movw r24,r26 + 4478 005a AA27 clr r26 + 4479 005c BB27 clr r27 + 4480 005e 868F std Z+30,r24 + 4481 0060 8A85 ldd r24,Y+10 + 4482 0062 9B85 ldd r25,Y+11 + 4483 0064 AC85 ldd r26,Y+12 + 4484 0066 BD85 ldd r27,Y+13 + 4485 0068 8B2F mov r24,r27 + 4486 006a 9927 clr r25 + 4487 006c AA27 clr r26 + 4488 006e BB27 clr r27 + 4489 0070 878F std Z+31,r24 + 4490 .LSM369: + 4491 0072 8E85 ldd r24,Y+14 + 4492 0074 828F std Z+26,r24 + 4493 0076 8F85 ldd r24,Y+15 + 4494 0078 838F std Z+27,r24 + 4495 .LSM370: + 4496 007a 8E85 ldd r24,Y+14 + 4497 007c 9F85 ldd r25,Y+15 + 4498 007e A889 ldd r26,Y+16 + 4499 0080 B989 ldd r27,Y+17 + 4500 0082 CD01 movw r24,r26 + 4501 0084 AA27 clr r26 + 4502 0086 BB27 clr r27 + 4503 0088 848B std Z+20,r24 + 4504 008a 8E85 ldd r24,Y+14 + 4505 008c 9F85 ldd r25,Y+15 + 4506 008e A889 ldd r26,Y+16 + 4507 0090 B989 ldd r27,Y+17 + 4508 0092 CD01 movw r24,r26 + 4509 0094 AA27 clr r26 + 4510 0096 BB27 clr r27 + 4511 0098 892F mov r24,r25 + 4512 009a 9927 clr r25 + 4513 009c 858B std Z+21,r24 + 4514 .LSM371: + 4515 009e 0E94 0000 call get_fattime + 4516 .LVL440: + 4517 .LSM372: + 4518 00a2 F801 movw r30,r16 + 4519 00a4 668B std Z+22,r22 + 4520 .LVL441: + 4521 00a6 272F mov r18,r23 + 4522 00a8 3327 clr r19 + 4523 00aa 278B std Z+23,r18 + 4524 00ac 9C01 movw r18,r24 + 4525 00ae 4427 clr r20 + 4526 00b0 5527 clr r21 + 4527 00b2 208F std Z+24,r18 + 4528 00b4 692F mov r22,r25 + 4529 00b6 7727 clr r23 + 4530 00b8 8827 clr r24 + 4531 00ba 9927 clr r25 + 4532 .LVL442: + 4533 00bc 618F std Z+25,r22 + 4534 .LSM373: + 4535 00be 8C81 ldd r24,Y+4 + 4536 00c0 8F7D andi r24,lo8(-33) + 4537 00c2 8C83 std Y+4,r24 + 4538 .LSM374: + 4539 00c4 E881 ld r30,Y + 4540 00c6 F981 ldd r31,Y+1 + 4541 00c8 81E0 ldi r24,lo8(1) + 4542 00ca 8483 std Z+4,r24 + 4543 .LSM375: + 4544 00cc 0990 ld __tmp_reg__,Y+ + 4545 00ce D881 ld r29,Y + 4546 00d0 C02D mov r28,__tmp_reg__ + 4547 .LVL443: + 4548 .LBB6: + 4549 .LSM376: + 4550 00d2 CE01 movw r24,r28 + 4551 00d4 40E0 ldi r20,lo8(0) + 4552 00d6 50E0 ldi r21,hi8(0) + 4553 00d8 60E0 ldi r22,hlo8(0) + 4554 00da 70E0 ldi r23,hhi8(0) + 4555 00dc 0E94 0000 call move_window + 4556 00e0 982F mov r25,r24 + 4557 .LVL444: + 4558 .LBB7: + 4559 .LSM377: + 4560 00e2 8823 tst r24 + 4561 00e4 01F0 breq .+2 + 4562 00e6 00C0 rjmp .L232 + 4563 .LVL445: + 4564 .LSM378: + 4565 00e8 8881 ld r24,Y + 4566 .LVL446: + 4567 00ea 8330 cpi r24,lo8(3) + 4568 00ec 01F0 breq .+2 + 4569 00ee 00C0 rjmp .L233 + 4570 00f0 8D81 ldd r24,Y+5 + 4571 00f2 8823 tst r24 + 4572 00f4 01F4 brne .+2 + 4573 00f6 00C0 rjmp .L233 + 4574 .LSM379: + 4575 00f8 1AA6 std Y+42,__zero_reg__ + 4576 00fa 1BA6 std Y+43,__zero_reg__ + 4577 00fc 1CA6 std Y+44,__zero_reg__ + 4578 00fe 1DA6 std Y+45,__zero_reg__ + 4579 .LSM380: + 4580 0100 8E01 movw r16,r28 + 4581 .LVL447: + 4582 0102 025D subi r16,lo8(-(46)) + 4583 0104 1F4F sbci r17,hi8(-(46)) + 4584 0106 C801 movw r24,r16 + 4585 0108 60E0 ldi r22,lo8(0) + 4586 010a 70E0 ldi r23,hi8(0) + 4587 010c 40E0 ldi r20,lo8(512) + 4588 010e 52E0 ldi r21,hi8(512) + 4589 0110 0E94 0000 call mem_set + 4590 .LVL448: + 4591 .LSM381: + 4592 0114 C45D subi r28,lo8(-(556)) + 4593 0116 DD4F sbci r29,hi8(-(556)) + 4594 0118 85E5 ldi r24,lo8(85) + 4595 011a 8993 st Y+,r24 + 4596 011c 8AEA ldi r24,lo8(-86) + 4597 011e 8883 st Y,r24 + 4598 0120 CD52 subi r28,lo8(-(-557)) + 4599 0122 D240 sbci r29,hi8(-(-557)) + 4600 .LSM382: + 4601 0124 82E5 ldi r24,lo8(82) + 4602 0126 8EA7 std Y+46,r24 + 4603 0128 8FA7 std Y+47,r24 + 4604 012a 21E6 ldi r18,lo8(97) + 4605 012c 28AB std Y+48,r18 + 4606 012e 91E4 ldi r25,lo8(65) + 4607 0130 99AB std Y+49,r25 + 4608 .LSM383: + 4609 0132 CE5E subi r28,lo8(-(530)) + 4610 0134 DD4F sbci r29,hi8(-(530)) + 4611 0136 82E7 ldi r24,lo8(114) + 4612 0138 8993 st Y+,r24 + 4613 013a 8993 st Y+,r24 + 4614 013c 9993 st Y+,r25 + 4615 013e 2883 st Y,r18 + 4616 0140 C551 subi r28,lo8(-(-533)) + 4617 0142 D240 sbci r29,hi8(-(-533)) + 4618 .LSM384: + 4619 0144 8E85 ldd r24,Y+14 + 4620 0146 CA5E subi r28,lo8(-(534)) + 4621 0148 DD4F sbci r29,hi8(-(534)) + 4622 014a 8883 st Y,r24 + 4623 014c C651 subi r28,lo8(-(-534)) + 4624 014e D240 sbci r29,hi8(-(-534)) + 4625 0150 8F85 ldd r24,Y+15 + 4626 0152 C95E subi r28,lo8(-(535)) + 4627 0154 DD4F sbci r29,hi8(-(535)) + 4628 0156 8883 st Y,r24 + 4629 0158 C751 subi r28,lo8(-(-535)) + 4630 015a D240 sbci r29,hi8(-(-535)) + 4631 015c 8E85 ldd r24,Y+14 + 4632 015e 9F85 ldd r25,Y+15 + 4633 0160 A889 ldd r26,Y+16 + 4634 0162 B989 ldd r27,Y+17 + 4635 0164 9D01 movw r18,r26 + 4636 0166 4427 clr r20 + 4637 0168 5527 clr r21 + 4638 016a C85E subi r28,lo8(-(536)) + 4639 016c DD4F sbci r29,hi8(-(536)) + 4640 016e 2883 st Y,r18 + 4641 0170 2196 adiw r28,1 + 4642 0172 8B2F mov r24,r27 + 4643 0174 9927 clr r25 + 4644 0176 AA27 clr r26 + 4645 0178 BB27 clr r27 + 4646 017a 8883 st Y,r24 + 4647 017c C951 subi r28,lo8(-(-537)) + 4648 017e D240 sbci r29,hi8(-(-537)) + 4649 .LSM385: + 4650 0180 8A85 ldd r24,Y+10 + 4651 0182 C65E subi r28,lo8(-(538)) + 4652 0184 DD4F sbci r29,hi8(-(538)) + 4653 0186 8883 st Y,r24 + 4654 0188 CA51 subi r28,lo8(-(-538)) + 4655 018a D240 sbci r29,hi8(-(-538)) + 4656 018c 8B85 ldd r24,Y+11 + 4657 018e C55E subi r28,lo8(-(539)) + 4658 0190 DD4F sbci r29,hi8(-(539)) + 4659 0192 8883 st Y,r24 + 4660 0194 CB51 subi r28,lo8(-(-539)) + 4661 0196 D240 sbci r29,hi8(-(-539)) + 4662 0198 8A85 ldd r24,Y+10 + 4663 019a 9B85 ldd r25,Y+11 + 4664 019c AC85 ldd r26,Y+12 + 4665 019e BD85 ldd r27,Y+13 + 4666 01a0 9D01 movw r18,r26 + 4667 01a2 4427 clr r20 + 4668 01a4 5527 clr r21 + 4669 01a6 C45E subi r28,lo8(-(540)) + 4670 01a8 DD4F sbci r29,hi8(-(540)) + 4671 01aa 2883 st Y,r18 + 4672 01ac 2196 adiw r28,1 + 4673 01ae 8B2F mov r24,r27 + 4674 01b0 9927 clr r25 + 4675 01b2 AA27 clr r26 + 4676 01b4 BB27 clr r27 + 4677 01b6 8883 st Y,r24 + 4678 01b8 CD51 subi r28,lo8(-(-541)) + 4679 01ba D240 sbci r29,hi8(-(-541)) + 4680 .LSM386: + 4681 01bc 2A89 ldd r18,Y+18 + 4682 01be 3B89 ldd r19,Y+19 + 4683 01c0 4C89 ldd r20,Y+20 + 4684 01c2 5D89 ldd r21,Y+21 + 4685 01c4 8981 ldd r24,Y+1 + 4686 01c6 B801 movw r22,r16 + 4687 01c8 01E0 ldi r16,lo8(1) + 4688 01ca 0E94 0000 call disk_write + 4689 .LSM387: + 4690 01ce 1D82 std Y+5,__zero_reg__ + 4691 .LVL449: + 4692 .L233: + 4693 .LBE7: + 4694 .LSM388: + 4695 01d0 8981 ldd r24,Y+1 + 4696 01d2 60E0 ldi r22,lo8(0) + 4697 01d4 40E0 ldi r20,lo8(0) + 4698 01d6 50E0 ldi r21,hi8(0) + 4699 01d8 0E94 0000 call disk_ioctl + 4700 .LVL450: + 4701 01dc 8111 cpse r24,__zero_reg__ + 4702 01de 81E0 ldi r24,lo8(1) + 4703 .L234: + 4704 01e0 982F mov r25,r24 + 4705 .LVL451: + 4706 .L232: + 4707 .LBE6: + 4708 .LSM389: + 4709 01e2 892F mov r24,r25 + 4710 /* epilogue start */ + 4711 01e4 DF91 pop r29 + 4712 01e6 CF91 pop r28 + 4713 .LVL452: + 4714 01e8 1F91 pop r17 + 4715 01ea 0F91 pop r16 + 4716 .LVL453: + 4717 01ec 0895 ret + 4718 .LFE76: + 4720 .section .text.f_close,"ax",@progbits + 4721 .global f_close + 4723 f_close: + 4724 .LFB77: + 4725 .LSM390: + 4726 .LVL454: + 4727 0000 CF93 push r28 + 4728 0002 DF93 push r29 + 4729 /* prologue: function */ + 4730 /* frame size = 0 */ + 4731 0004 EC01 movw r28,r24 + 4732 .LSM391: + 4733 0006 0E94 0000 call f_sync + 4734 .LVL455: + 4735 .LSM392: + 4736 000a 8823 tst r24 + 4737 .LVL456: + 4738 000c 01F4 brne .L237 + 4739 000e 1982 std Y+1,__zero_reg__ + 4740 0010 1882 st Y,__zero_reg__ + 4741 .L237: + 4742 .LVL457: + 4743 /* epilogue start */ + 4744 .LSM393: + 4745 0012 DF91 pop r29 + 4746 0014 CF91 pop r28 + 4747 .LVL458: + 4748 0016 0895 ret + 4749 .LFE77: + 4751 .section .text.chk_mounted,"ax",@progbits + 4752 .global chk_mounted + 4754 chk_mounted: + 4755 .LFB70: + 4756 .LSM394: + 4757 .LVL459: + 4758 0000 6F92 push r6 + 4759 0002 7F92 push r7 + 4760 0004 8F92 push r8 + 4761 0006 9F92 push r9 + 4762 0008 AF92 push r10 + 4763 000a BF92 push r11 + 4764 000c CF92 push r12 + 4765 000e DF92 push r13 + 4766 0010 EF92 push r14 + 4767 0012 FF92 push r15 + 4768 0014 0F93 push r16 + 4769 0016 1F93 push r17 + 4770 0018 CF93 push r28 + 4771 001a DF93 push r29 + 4772 /* prologue: function */ + 4773 /* frame size = 0 */ + 4774 001c DC01 movw r26,r24 + 4775 001e 142F mov r17,r20 + 4776 .LSM395: + 4777 0020 ED91 ld r30,X+ + 4778 0022 FC91 ld r31,X + 4779 0024 1197 sbiw r26,1 + 4780 .LVL460: + 4781 .LSM396: + 4782 0026 8081 ld r24,Z + 4783 .LVL461: + 4784 0028 282F mov r18,r24 + 4785 .LVL462: + 4786 002a 30E0 ldi r19,lo8(0) + 4787 .LVL463: + 4788 002c 2053 subi r18,lo8(-(-48)) + 4789 002e 3040 sbci r19,hi8(-(-48)) + 4790 .LVL464: + 4791 .LSM397: + 4792 0030 2A30 cpi r18,10 + 4793 0032 3105 cpc r19,__zero_reg__ + 4794 0034 00F4 brsh .L240 + 4795 .LVL465: + 4796 0036 8181 ldd r24,Z+1 + 4797 0038 8A33 cpi r24,lo8(58) + 4798 003a 01F4 brne .L240 + 4799 .LSM398: + 4800 003c 3296 adiw r30,2 + 4801 003e ED93 st X+,r30 + 4802 0040 FC93 st X,r31 + 4803 .LSM399: + 4804 0042 232B or r18,r19 + 4805 0044 01F0 breq .L240 + 4806 0046 8BE0 ldi r24,lo8(11) + 4807 0048 00C0 rjmp .L241 + 4808 .L240: + 4809 .LSM400: + 4810 004a C091 0000 lds r28,FatFs + 4811 004e D091 0000 lds r29,(FatFs)+1 + 4812 .LVL466: + 4813 0052 FB01 movw r30,r22 + 4814 .LVL467: + 4815 0054 D183 std Z+1,r29 + 4816 0056 C083 st Z,r28 + 4817 .LSM401: + 4818 0058 2097 sbiw r28,0 + 4819 005a 01F4 brne .L242 + 4820 005c 8CE0 ldi r24,lo8(12) + 4821 005e 00C0 rjmp .L241 + 4822 .L242: + 4823 .LSM402: + 4824 0060 8881 ld r24,Y + 4825 0062 8823 tst r24 + 4826 0064 01F0 breq .L243 + 4827 .LSM403: + 4828 0066 8981 ldd r24,Y+1 + 4829 0068 0E94 0000 call disk_status + 4830 .LVL468: + 4831 .LSM404: + 4832 006c 80FD sbrc r24,0 + 4833 006e 00C0 rjmp .L243 + 4834 .LSM405: + 4835 0070 1123 tst r17 + 4836 0072 01F4 brne .+2 + 4837 0074 00C0 rjmp .L244 + 4838 0076 82FD sbrc r24,2 + 4839 0078 00C0 rjmp .L245 + 4840 007a 00C0 rjmp .L244 + 4841 .LVL469: + 4842 .L243: + 4843 .LSM406: + 4844 007c 1882 st Y,__zero_reg__ + 4845 .LSM407: + 4846 007e 1982 std Y+1,__zero_reg__ + 4847 .LSM408: + 4848 0080 80E0 ldi r24,lo8(0) + 4849 0082 0E94 0000 call disk_initialize + 4850 .LVL470: + 4851 .LSM409: + 4852 0086 80FF sbrs r24,0 + 4853 0088 00C0 rjmp .L246 + 4854 008a 83E0 ldi r24,lo8(3) + 4855 008c 00C0 rjmp .L241 + 4856 .L246: + 4857 .LSM410: + 4858 008e 1123 tst r17 + 4859 0090 01F0 breq .L247 + 4860 0092 82FD sbrc r24,2 + 4861 0094 00C0 rjmp .L245 + 4862 .L247: + 4863 .LSM411: + 4864 0096 CE01 movw r24,r28 + 4865 0098 40E0 ldi r20,lo8(0) + 4866 009a 50E0 ldi r21,hi8(0) + 4867 009c 60E0 ldi r22,hlo8(0) + 4868 009e 70E0 ldi r23,hhi8(0) + 4869 00a0 0E94 0000 call check_fs + 4870 .LSM412: + 4871 00a4 8130 cpi r24,lo8(1) + 4872 .LVL471: + 4873 00a6 01F0 breq .L248 + 4874 00a8 AA24 clr r10 + 4875 00aa BB24 clr r11 + 4876 00ac 6501 movw r12,r10 + 4877 .LVL472: + 4878 00ae 00C0 rjmp .L249 + 4879 .LVL473: + 4880 .L248: + 4881 .LSM413: + 4882 00b0 FE01 movw r30,r28 + 4883 .LVL474: + 4884 00b2 E451 subi r30,lo8(-(492)) + 4885 00b4 FE4F sbci r31,hi8(-(492)) + 4886 .LSM414: + 4887 00b6 8481 ldd r24,Z+4 + 4888 .LVL475: + 4889 00b8 8823 tst r24 + 4890 00ba 01F4 brne .+2 + 4891 00bc 00C0 rjmp .L250 + 4892 .LSM415: + 4893 00be 8385 ldd r24,Z+11 + 4894 00c0 90E0 ldi r25,lo8(0) + 4895 00c2 A0E0 ldi r26,lo8(0) + 4896 00c4 B0E0 ldi r27,hi8(0) + 4897 00c6 D82E mov r13,r24 + 4898 00c8 CC24 clr r12 + 4899 00ca BB24 clr r11 + 4900 00cc AA24 clr r10 + 4901 .LVL476: + 4902 00ce 8285 ldd r24,Z+10 + 4903 00d0 90E0 ldi r25,lo8(0) + 4904 00d2 A0E0 ldi r26,lo8(0) + 4905 00d4 B0E0 ldi r27,hi8(0) + 4906 00d6 DC01 movw r26,r24 + 4907 00d8 9927 clr r25 + 4908 00da 8827 clr r24 + 4909 00dc A82A or r10,r24 + 4910 00de B92A or r11,r25 + 4911 00e0 CA2A or r12,r26 + 4912 00e2 DB2A or r13,r27 + 4913 00e4 8085 ldd r24,Z+8 + 4914 00e6 90E0 ldi r25,lo8(0) + 4915 00e8 A0E0 ldi r26,lo8(0) + 4916 00ea B0E0 ldi r27,hi8(0) + 4917 00ec A82A or r10,r24 + 4918 00ee B92A or r11,r25 + 4919 00f0 CA2A or r12,r26 + 4920 00f2 DB2A or r13,r27 + 4921 00f4 9185 ldd r25,Z+9 + 4922 00f6 80E0 ldi r24,lo8(0) + 4923 00f8 A0E0 ldi r26,lo8(0) + 4924 00fa B0E0 ldi r27,hi8(0) + 4925 00fc A82A or r10,r24 + 4926 00fe B92A or r11,r25 + 4927 0100 CA2A or r12,r26 + 4928 0102 DB2A or r13,r27 + 4929 .LSM416: + 4930 0104 CE01 movw r24,r28 + 4931 0106 B601 movw r22,r12 + 4932 0108 A501 movw r20,r10 + 4933 010a 0E94 0000 call check_fs + 4934 .LVL477: + 4935 .L249: + 4936 .LSM417: + 4937 010e 8330 cpi r24,lo8(3) + 4938 0110 01F4 brne .L251 + 4939 0112 81E0 ldi r24,lo8(1) + 4940 .LVL478: + 4941 0114 00C0 rjmp .L241 + 4942 .LVL479: + 4943 .L251: + 4944 .LSM418: + 4945 0116 8823 tst r24 + 4946 0118 01F0 breq .+2 + 4947 011a 00C0 rjmp .L250 + 4948 011c 9AAD ldd r25,Y+58 + 4949 011e 80E0 ldi r24,lo8(0) + 4950 .LVL480: + 4951 0120 29AD ldd r18,Y+57 + 4952 0122 30E0 ldi r19,lo8(0) + 4953 0124 822B or r24,r18 + 4954 0126 932B or r25,r19 + 4955 0128 8050 subi r24,lo8(512) + 4956 012a 9240 sbci r25,hi8(512) + 4957 012c 01F0 breq .+2 + 4958 012e 00C0 rjmp .L250 + 4959 .LSM419: + 4960 0130 CB5B subi r28,lo8(-(69)) + 4961 0132 DF4F sbci r29,hi8(-(69)) + 4962 0134 9881 ld r25,Y + 4963 0136 80E0 ldi r24,lo8(0) + 4964 0138 2A91 ld r18,-Y + 4965 013a C454 subi r28,lo8(-(-68)) + 4966 013c D040 sbci r29,hi8(-(-68)) + 4967 013e 30E0 ldi r19,lo8(0) + 4968 0140 822B or r24,r18 + 4969 0142 932B or r25,r19 + 4970 0144 7C01 movw r14,r24 + 4971 .LVL481: + 4972 0146 00E0 ldi r16,lo8(0) + 4973 0148 10E0 ldi r17,hi8(0) + 4974 .LVL482: + 4975 .LSM420: + 4976 014a E114 cp r14,__zero_reg__ + 4977 014c F104 cpc r15,__zero_reg__ + 4978 014e 0105 cpc r16,__zero_reg__ + 4979 0150 1105 cpc r17,__zero_reg__ + 4980 0152 01F4 brne .L252 + 4981 0154 CB5A subi r28,lo8(-(85)) + 4982 0156 DF4F sbci r29,hi8(-(85)) + 4983 0158 8881 ld r24,Y + 4984 015a 90E0 ldi r25,lo8(0) + 4985 015c A0E0 ldi r26,lo8(0) + 4986 015e B0E0 ldi r27,hi8(0) + 4987 0160 182F mov r17,r24 + 4988 0162 0027 clr r16 + 4989 0164 FF24 clr r15 + 4990 0166 EE24 clr r14 + 4991 .LVL483: + 4992 0168 8A91 ld r24,-Y + 4993 016a 90E0 ldi r25,lo8(0) + 4994 016c A0E0 ldi r26,lo8(0) + 4995 016e B0E0 ldi r27,hi8(0) + 4996 0170 DC01 movw r26,r24 + 4997 0172 9927 clr r25 + 4998 0174 8827 clr r24 + 4999 0176 E82A or r14,r24 + 5000 0178 F92A or r15,r25 + 5001 017a 0A2B or r16,r26 + 5002 017c 1B2B or r17,r27 + 5003 017e 2297 sbiw r28,2 + 5004 0180 8991 ld r24,Y+ + 5005 0182 90E0 ldi r25,lo8(0) + 5006 0184 A0E0 ldi r26,lo8(0) + 5007 0186 B0E0 ldi r27,hi8(0) + 5008 0188 E82A or r14,r24 + 5009 018a F92A or r15,r25 + 5010 018c 0A2B or r16,r26 + 5011 018e 1B2B or r17,r27 + 5012 0190 9881 ld r25,Y + 5013 0192 C355 subi r28,lo8(-(-83)) + 5014 0194 D040 sbci r29,hi8(-(-83)) + 5015 0196 80E0 ldi r24,lo8(0) + 5016 0198 A0E0 ldi r26,lo8(0) + 5017 019a B0E0 ldi r27,hi8(0) + 5018 019c E82A or r14,r24 + 5019 019e F92A or r15,r25 + 5020 01a0 0A2B or r16,r26 + 5021 01a2 1B2B or r17,r27 + 5022 .L252: + 5023 .LSM421: + 5024 01a4 EE8A std Y+22,r14 + 5025 01a6 FF8A std Y+23,r15 + 5026 01a8 088F std Y+24,r16 + 5027 01aa 198F std Y+25,r17 + 5028 .LSM422: + 5029 01ac 2EAD ldd r18,Y+62 + 5030 01ae 2B83 std Y+3,r18 + 5031 .LSM423: + 5032 01b0 30E0 ldi r19,lo8(0) + 5033 01b2 40E0 ldi r20,lo8(0) + 5034 01b4 50E0 ldi r21,hi8(0) + 5035 01b6 C801 movw r24,r16 + 5036 01b8 B701 movw r22,r14 + 5037 01ba 0E94 0000 call __mulsi3 + 5038 01be 3B01 movw r6,r22 + 5039 01c0 4C01 movw r8,r24 + 5040 .LVL484: + 5041 .LSM424: + 5042 01c2 9DAD ldd r25,Y+61 + 5043 01c4 80E0 ldi r24,lo8(0) + 5044 01c6 2CAD ldd r18,Y+60 + 5045 01c8 30E0 ldi r19,lo8(0) + 5046 01ca 822B or r24,r18 + 5047 01cc 932B or r25,r19 + 5048 01ce A0E0 ldi r26,lo8(0) + 5049 01d0 B0E0 ldi r27,hi8(0) + 5050 01d2 8A0D add r24,r10 + 5051 01d4 9B1D adc r25,r11 + 5052 01d6 AC1D adc r26,r12 + 5053 01d8 BD1D adc r27,r13 + 5054 01da 8E8F std Y+30,r24 + 5055 01dc 9F8F std Y+31,r25 + 5056 01de A8A3 std Y+32,r26 + 5057 01e0 B9A3 std Y+33,r27 + 5058 .LSM425: + 5059 01e2 8BAD ldd r24,Y+59 + 5060 01e4 8A83 std Y+2,r24 + 5061 .LSM426: + 5062 01e6 C05C subi r28,lo8(-(64)) + 5063 01e8 DF4F sbci r29,hi8(-(64)) + 5064 01ea 9881 ld r25,Y + 5065 01ec C054 subi r28,lo8(-(-64)) + 5066 01ee D040 sbci r29,hi8(-(-64)) + 5067 01f0 80E0 ldi r24,lo8(0) + 5068 01f2 2FAD ldd r18,Y+63 + 5069 01f4 422F mov r20,r18 + 5070 01f6 50E0 ldi r21,lo8(0) + 5071 01f8 482B or r20,r24 + 5072 01fa 592B or r21,r25 + 5073 01fc 5987 std Y+9,r21 + 5074 01fe 4887 std Y+8,r20 + 5075 .LSM427: + 5076 0200 CE5B subi r28,lo8(-(66)) + 5077 0202 DF4F sbci r29,hi8(-(66)) + 5078 0204 9881 ld r25,Y + 5079 0206 80E0 ldi r24,lo8(0) + 5080 0208 2A91 ld r18,-Y + 5081 020a C154 subi r28,lo8(-(-65)) + 5082 020c D040 sbci r29,hi8(-(-65)) + 5083 020e 30E0 ldi r19,lo8(0) + 5084 0210 822B or r24,r18 + 5085 0212 932B or r25,r19 + 5086 0214 7C01 movw r14,r24 + 5087 .LVL485: + 5088 0216 00E0 ldi r16,lo8(0) + 5089 0218 10E0 ldi r17,hi8(0) + 5090 .LVL486: + 5091 .LSM428: + 5092 021a E114 cp r14,__zero_reg__ + 5093 021c F104 cpc r15,__zero_reg__ + 5094 021e 0105 cpc r16,__zero_reg__ + 5095 0220 1105 cpc r17,__zero_reg__ + 5096 0222 01F4 brne .L253 + 5097 0224 CF5A subi r28,lo8(-(81)) + 5098 0226 DF4F sbci r29,hi8(-(81)) + 5099 0228 8881 ld r24,Y + 5100 022a 90E0 ldi r25,lo8(0) + 5101 022c A0E0 ldi r26,lo8(0) + 5102 022e B0E0 ldi r27,hi8(0) + 5103 0230 182F mov r17,r24 + 5104 0232 0027 clr r16 + 5105 0234 FF24 clr r15 + 5106 0236 EE24 clr r14 + 5107 .LVL487: + 5108 0238 8A91 ld r24,-Y + 5109 023a 90E0 ldi r25,lo8(0) + 5110 023c A0E0 ldi r26,lo8(0) + 5111 023e B0E0 ldi r27,hi8(0) + 5112 0240 DC01 movw r26,r24 + 5113 0242 9927 clr r25 + 5114 0244 8827 clr r24 + 5115 0246 E82A or r14,r24 + 5116 0248 F92A or r15,r25 + 5117 024a 0A2B or r16,r26 + 5118 024c 1B2B or r17,r27 + 5119 024e 2297 sbiw r28,2 + 5120 0250 8991 ld r24,Y+ + 5121 0252 90E0 ldi r25,lo8(0) + 5122 0254 A0E0 ldi r26,lo8(0) + 5123 0256 B0E0 ldi r27,hi8(0) + 5124 0258 E82A or r14,r24 + 5125 025a F92A or r15,r25 + 5126 025c 0A2B or r16,r26 + 5127 025e 1B2B or r17,r27 + 5128 0260 9881 ld r25,Y + 5129 0262 CF54 subi r28,lo8(-(-79)) + 5130 0264 D040 sbci r29,hi8(-(-79)) + 5131 0266 80E0 ldi r24,lo8(0) + 5132 0268 A0E0 ldi r26,lo8(0) + 5133 026a B0E0 ldi r27,hi8(0) + 5134 026c E82A or r14,r24 + 5135 026e F92A or r15,r25 + 5136 0270 0A2B or r16,r26 + 5137 0272 1B2B or r17,r27 + 5138 .L253: + 5139 .LSM429: + 5140 0274 9DAD ldd r25,Y+61 + 5141 0276 80E0 ldi r24,lo8(0) + 5142 0278 2CAD ldd r18,Y+60 + 5143 027a 30E0 ldi r19,lo8(0) + 5144 027c 822B or r24,r18 + 5145 027e 932B or r25,r19 + 5146 0280 A0E0 ldi r26,lo8(0) + 5147 0282 B0E0 ldi r27,hi8(0) + 5148 0284 E81A sub r14,r24 + 5149 0286 F90A sbc r15,r25 + 5150 0288 0A0B sbc r16,r26 + 5151 028a 1B0B sbc r17,r27 + 5152 .LVL488: + 5153 028c E618 sub r14,r6 + 5154 028e F708 sbc r15,r7 + 5155 0290 0809 sbc r16,r8 + 5156 0292 1909 sbc r17,r9 + 5157 0294 B4E0 ldi r27,4 + 5158 0296 5695 1: lsr r21 + 5159 0298 4795 ror r20 + 5160 029a BA95 dec r27 + 5161 029c 01F4 brne 1b + 5162 029e CA01 movw r24,r20 + 5163 02a0 A0E0 ldi r26,lo8(0) + 5164 02a2 B0E0 ldi r27,hi8(0) + 5165 02a4 E81A sub r14,r24 + 5166 02a6 F90A sbc r15,r25 + 5167 02a8 0A0B sbc r16,r26 + 5168 02aa 1B0B sbc r17,r27 + 5169 02ac 2A81 ldd r18,Y+2 + 5170 02ae 30E0 ldi r19,lo8(0) + 5171 02b0 40E0 ldi r20,lo8(0) + 5172 02b2 50E0 ldi r21,hi8(0) + 5173 02b4 C801 movw r24,r16 + 5174 02b6 B701 movw r22,r14 + 5175 02b8 0E94 0000 call __udivmodsi4 + 5176 02bc 2E5F subi r18,lo8(-(2)) + 5177 02be 3F4F sbci r19,hi8(-(2)) + 5178 02c0 4F4F sbci r20,hlo8(-(2)) + 5179 02c2 5F4F sbci r21,hhi8(-(2)) + 5180 .LVL489: + 5181 02c4 2A8F std Y+26,r18 + 5182 02c6 3B8F std Y+27,r19 + 5183 02c8 4C8F std Y+28,r20 + 5184 02ca 5D8F std Y+29,r21 + 5185 .LSM430: + 5186 02cc 273F cpi r18,lo8(4087) + 5187 02ce 8FE0 ldi r24,hi8(4087) + 5188 02d0 3807 cpc r19,r24 + 5189 02d2 80E0 ldi r24,hlo8(4087) + 5190 02d4 4807 cpc r20,r24 + 5191 02d6 80E0 ldi r24,hhi8(4087) + 5192 02d8 5807 cpc r21,r24 + 5193 02da 00F4 brsh .L254 + 5194 02dc 11E0 ldi r17,lo8(1) + 5195 .LVL490: + 5196 02de 00C0 rjmp .L255 + 5197 .LVL491: + 5198 .L254: + 5199 .LSM431: + 5200 02e0 275F subi r18,lo8(65527) + 5201 02e2 3F4F sbci r19,hi8(65527) + 5202 02e4 4040 sbci r20,hlo8(65527) + 5203 02e6 5040 sbci r21,hhi8(65527) + 5204 02e8 00F0 brlo .+2 + 5205 02ea 00C0 rjmp .L256 + 5206 02ec 12E0 ldi r17,lo8(2) + 5207 .LVL492: + 5208 .L255: + 5209 .LSM432: + 5210 02ee 8E8D ldd r24,Y+30 + 5211 02f0 9F8D ldd r25,Y+31 + 5212 02f2 A8A1 ldd r26,Y+32 + 5213 02f4 B9A1 ldd r27,Y+33 + 5214 02f6 860D add r24,r6 + 5215 02f8 971D adc r25,r7 + 5216 02fa A81D adc r26,r8 + 5217 02fc B91D adc r27,r9 + 5218 02fe 8AA3 std Y+34,r24 + 5219 0300 9BA3 std Y+35,r25 + 5220 0302 ACA3 std Y+36,r26 + 5221 0304 BDA3 std Y+37,r27 + 5222 .L258: + 5223 .LSM433: + 5224 0306 8885 ldd r24,Y+8 + 5225 0308 9985 ldd r25,Y+9 + 5226 030a A4E0 ldi r26,4 + 5227 030c 9695 1: lsr r25 + 5228 030e 8795 ror r24 + 5229 0310 AA95 dec r26 + 5230 0312 01F4 brne 1b + 5231 0314 A0E0 ldi r26,lo8(0) + 5232 0316 B0E0 ldi r27,hi8(0) + 5233 0318 2E8D ldd r18,Y+30 + 5234 031a 3F8D ldd r19,Y+31 + 5235 031c 48A1 ldd r20,Y+32 + 5236 031e 59A1 ldd r21,Y+33 + 5237 .LVL493: + 5238 0320 820F add r24,r18 + 5239 0322 931F adc r25,r19 + 5240 0324 A41F adc r26,r20 + 5241 0326 B51F adc r27,r21 + 5242 0328 860D add r24,r6 + 5243 032a 971D adc r25,r7 + 5244 032c A81D adc r26,r8 + 5245 032e B91D adc r27,r9 + 5246 0330 8EA3 std Y+38,r24 + 5247 0332 9FA3 std Y+39,r25 + 5248 0334 A8A7 std Y+40,r26 + 5249 0336 B9A7 std Y+41,r27 + 5250 .LSM434: + 5251 0338 8FEF ldi r24,lo8(-1) + 5252 033a 9FEF ldi r25,hi8(-1) + 5253 033c AFEF ldi r26,hlo8(-1) + 5254 033e BFEF ldi r27,hhi8(-1) + 5255 0340 8E87 std Y+14,r24 + 5256 0342 9F87 std Y+15,r25 + 5257 0344 A88B std Y+16,r26 + 5258 0346 B98B std Y+17,r27 + 5259 .LSM435: + 5260 0348 1C82 std Y+4,__zero_reg__ + 5261 .LSM436: + 5262 034a 1330 cpi r17,lo8(3) + 5263 034c 01F0 breq .+2 + 5264 034e 00C0 rjmp .L257 + 5265 .LSM437: + 5266 0350 1D82 std Y+5,__zero_reg__ + 5267 .LSM438: + 5268 0352 C15A subi r28,lo8(-(95)) + 5269 0354 DF4F sbci r29,hi8(-(95)) + 5270 0356 3881 ld r19,Y + 5271 0358 20E0 ldi r18,lo8(0) + 5272 035a 8A91 ld r24,-Y + 5273 035c CE55 subi r28,lo8(-(-94)) + 5274 035e D040 sbci r29,hi8(-(-94)) + 5275 0360 90E0 ldi r25,lo8(0) + 5276 0362 282B or r18,r24 + 5277 0364 392B or r19,r25 + 5278 0366 40E0 ldi r20,lo8(0) + 5279 0368 50E0 ldi r21,hi8(0) + 5280 036a 2A0D add r18,r10 + 5281 036c 3B1D adc r19,r11 + 5282 036e 4C1D adc r20,r12 + 5283 0370 5D1D adc r21,r13 + 5284 0372 2A8B std Y+18,r18 + 5285 0374 3B8B std Y+19,r19 + 5286 0376 4C8B std Y+20,r20 + 5287 0378 5D8B std Y+21,r21 + 5288 .LSM439: + 5289 037a BE01 movw r22,r28 + 5290 037c 625D subi r22,lo8(-(46)) + 5291 037e 7F4F sbci r23,hi8(-(46)) + 5292 0380 8981 ldd r24,Y+1 + 5293 0382 01E0 ldi r16,lo8(1) + 5294 .LVL494: + 5295 0384 0E94 0000 call disk_read + 5296 0388 8823 tst r24 + 5297 038a 01F0 breq .+2 + 5298 038c 00C0 rjmp .L257 + 5299 038e C35D subi r28,lo8(-(557)) + 5300 0390 DD4F sbci r29,hi8(-(557)) + 5301 0392 9881 ld r25,Y + 5302 0394 80E0 ldi r24,lo8(0) + 5303 0396 2A91 ld r18,-Y + 5304 0398 CC52 subi r28,lo8(-(-556)) + 5305 039a D240 sbci r29,hi8(-(-556)) + 5306 039c 30E0 ldi r19,lo8(0) + 5307 039e 822B or r24,r18 + 5308 03a0 932B or r25,r19 + 5309 03a2 8555 subi r24,lo8(-21931) + 5310 03a4 9A4A sbci r25,hi8(-21931) + 5311 03a6 01F0 breq .+2 + 5312 03a8 00C0 rjmp .L257 + 5313 03aa 29A9 ldd r18,Y+49 + 5314 03ac 30E0 ldi r19,lo8(0) + 5315 03ae 40E0 ldi r20,lo8(0) + 5316 03b0 50E0 ldi r21,hi8(0) + 5317 03b2 522F mov r21,r18 + 5318 03b4 4427 clr r20 + 5319 03b6 3327 clr r19 + 5320 03b8 2227 clr r18 + 5321 03ba 88A9 ldd r24,Y+48 + 5322 03bc 90E0 ldi r25,lo8(0) + 5323 03be A0E0 ldi r26,lo8(0) + 5324 03c0 B0E0 ldi r27,hi8(0) + 5325 03c2 DC01 movw r26,r24 + 5326 03c4 9927 clr r25 + 5327 03c6 8827 clr r24 + 5328 03c8 282B or r18,r24 + 5329 03ca 392B or r19,r25 + 5330 03cc 4A2B or r20,r26 + 5331 03ce 5B2B or r21,r27 + 5332 03d0 8EA5 ldd r24,Y+46 + 5333 03d2 90E0 ldi r25,lo8(0) + 5334 03d4 A0E0 ldi r26,lo8(0) + 5335 03d6 B0E0 ldi r27,hi8(0) + 5336 03d8 282B or r18,r24 + 5337 03da 392B or r19,r25 + 5338 03dc 4A2B or r20,r26 + 5339 03de 5B2B or r21,r27 + 5340 03e0 9FA5 ldd r25,Y+47 + 5341 03e2 80E0 ldi r24,lo8(0) + 5342 03e4 A0E0 ldi r26,lo8(0) + 5343 03e6 B0E0 ldi r27,hi8(0) + 5344 03e8 282B or r18,r24 + 5345 03ea 392B or r19,r25 + 5346 03ec 4A2B or r20,r26 + 5347 03ee 5B2B or r21,r27 + 5348 03f0 2255 subi r18,lo8(1096897106) + 5349 03f2 3245 sbci r19,hi8(1096897106) + 5350 03f4 4146 sbci r20,hlo8(1096897106) + 5351 03f6 5144 sbci r21,hhi8(1096897106) + 5352 03f8 01F0 breq .+2 + 5353 03fa 00C0 rjmp .L257 + 5354 03fc CB5E subi r28,lo8(-(533)) + 5355 03fe DD4F sbci r29,hi8(-(533)) + 5356 0400 2881 ld r18,Y + 5357 0402 30E0 ldi r19,lo8(0) + 5358 0404 40E0 ldi r20,lo8(0) + 5359 0406 50E0 ldi r21,hi8(0) + 5360 0408 522F mov r21,r18 + 5361 040a 4427 clr r20 + 5362 040c 3327 clr r19 + 5363 040e 2227 clr r18 + 5364 0410 8A91 ld r24,-Y + 5365 0412 90E0 ldi r25,lo8(0) + 5366 0414 A0E0 ldi r26,lo8(0) + 5367 0416 B0E0 ldi r27,hi8(0) + 5368 0418 DC01 movw r26,r24 + 5369 041a 9927 clr r25 + 5370 041c 8827 clr r24 + 5371 041e 282B or r18,r24 + 5372 0420 392B or r19,r25 + 5373 0422 4A2B or r20,r26 + 5374 0424 5B2B or r21,r27 + 5375 0426 2297 sbiw r28,2 + 5376 0428 8991 ld r24,Y+ + 5377 042a 90E0 ldi r25,lo8(0) + 5378 042c A0E0 ldi r26,lo8(0) + 5379 042e B0E0 ldi r27,hi8(0) + 5380 0430 282B or r18,r24 + 5381 0432 392B or r19,r25 + 5382 0434 4A2B or r20,r26 + 5383 0436 5B2B or r21,r27 + 5384 0438 9881 ld r25,Y + 5385 043a C351 subi r28,lo8(-(-531)) + 5386 043c D240 sbci r29,hi8(-(-531)) + 5387 043e 80E0 ldi r24,lo8(0) + 5388 0440 A0E0 ldi r26,lo8(0) + 5389 0442 B0E0 ldi r27,hi8(0) + 5390 0444 282B or r18,r24 + 5391 0446 392B or r19,r25 + 5392 0448 4A2B or r20,r26 + 5393 044a 5B2B or r21,r27 + 5394 044c 2257 subi r18,lo8(1631679090) + 5395 044e 3247 sbci r19,hi8(1631679090) + 5396 0450 4144 sbci r20,hlo8(1631679090) + 5397 0452 5146 sbci r21,hhi8(1631679090) + 5398 0454 01F0 breq .+2 + 5399 0456 00C0 rjmp .L257 + 5400 .LSM440: + 5401 0458 C35E subi r28,lo8(-(541)) + 5402 045a DD4F sbci r29,hi8(-(541)) + 5403 045c 2881 ld r18,Y + 5404 045e 30E0 ldi r19,lo8(0) + 5405 0460 40E0 ldi r20,lo8(0) + 5406 0462 50E0 ldi r21,hi8(0) + 5407 0464 522F mov r21,r18 + 5408 0466 4427 clr r20 + 5409 0468 3327 clr r19 + 5410 046a 2227 clr r18 + 5411 046c 8A91 ld r24,-Y + 5412 046e 90E0 ldi r25,lo8(0) + 5413 0470 A0E0 ldi r26,lo8(0) + 5414 0472 B0E0 ldi r27,hi8(0) + 5415 0474 DC01 movw r26,r24 + 5416 0476 9927 clr r25 + 5417 0478 8827 clr r24 + 5418 047a 282B or r18,r24 + 5419 047c 392B or r19,r25 + 5420 047e 4A2B or r20,r26 + 5421 0480 5B2B or r21,r27 + 5422 0482 2297 sbiw r28,2 + 5423 0484 8991 ld r24,Y+ + 5424 0486 90E0 ldi r25,lo8(0) + 5425 0488 A0E0 ldi r26,lo8(0) + 5426 048a B0E0 ldi r27,hi8(0) + 5427 048c 282B or r18,r24 + 5428 048e 392B or r19,r25 + 5429 0490 4A2B or r20,r26 + 5430 0492 5B2B or r21,r27 + 5431 0494 9881 ld r25,Y + 5432 0496 CB51 subi r28,lo8(-(-539)) + 5433 0498 D240 sbci r29,hi8(-(-539)) + 5434 049a 80E0 ldi r24,lo8(0) + 5435 049c A0E0 ldi r26,lo8(0) + 5436 049e B0E0 ldi r27,hi8(0) + 5437 04a0 282B or r18,r24 + 5438 04a2 392B or r19,r25 + 5439 04a4 4A2B or r20,r26 + 5440 04a6 5B2B or r21,r27 + 5441 04a8 2A87 std Y+10,r18 + 5442 04aa 3B87 std Y+11,r19 + 5443 04ac 4C87 std Y+12,r20 + 5444 04ae 5D87 std Y+13,r21 + 5445 .LSM441: + 5446 04b0 C75E subi r28,lo8(-(537)) + 5447 04b2 DD4F sbci r29,hi8(-(537)) + 5448 04b4 2881 ld r18,Y + 5449 04b6 30E0 ldi r19,lo8(0) + 5450 04b8 40E0 ldi r20,lo8(0) + 5451 04ba 50E0 ldi r21,hi8(0) + 5452 04bc 522F mov r21,r18 + 5453 04be 4427 clr r20 + 5454 04c0 3327 clr r19 + 5455 04c2 2227 clr r18 + 5456 04c4 8A91 ld r24,-Y + 5457 04c6 90E0 ldi r25,lo8(0) + 5458 04c8 A0E0 ldi r26,lo8(0) + 5459 04ca B0E0 ldi r27,hi8(0) + 5460 04cc DC01 movw r26,r24 + 5461 04ce 9927 clr r25 + 5462 04d0 8827 clr r24 + 5463 04d2 282B or r18,r24 + 5464 04d4 392B or r19,r25 + 5465 04d6 4A2B or r20,r26 + 5466 04d8 5B2B or r21,r27 + 5467 04da 2297 sbiw r28,2 + 5468 04dc 8991 ld r24,Y+ + 5469 04de 90E0 ldi r25,lo8(0) + 5470 04e0 A0E0 ldi r26,lo8(0) + 5471 04e2 B0E0 ldi r27,hi8(0) + 5472 04e4 282B or r18,r24 + 5473 04e6 392B or r19,r25 + 5474 04e8 4A2B or r20,r26 + 5475 04ea 5B2B or r21,r27 + 5476 04ec 9881 ld r25,Y + 5477 04ee C751 subi r28,lo8(-(-535)) + 5478 04f0 D240 sbci r29,hi8(-(-535)) + 5479 04f2 80E0 ldi r24,lo8(0) + 5480 04f4 A0E0 ldi r26,lo8(0) + 5481 04f6 B0E0 ldi r27,hi8(0) + 5482 04f8 282B or r18,r24 + 5483 04fa 392B or r19,r25 + 5484 04fc 4A2B or r20,r26 + 5485 04fe 5B2B or r21,r27 + 5486 0500 2E87 std Y+14,r18 + 5487 0502 3F87 std Y+15,r19 + 5488 0504 488B std Y+16,r20 + 5489 0506 598B std Y+17,r21 + 5490 .LVL495: + 5491 .L257: + 5492 .LSM442: + 5493 0508 1883 st Y,r17 + 5494 .LSM443: + 5495 050a 1AA6 std Y+42,__zero_reg__ + 5496 050c 1BA6 std Y+43,__zero_reg__ + 5497 050e 1CA6 std Y+44,__zero_reg__ + 5498 0510 1DA6 std Y+45,__zero_reg__ + 5499 .LSM444: + 5500 0512 8091 0000 lds r24,Fsid + 5501 0516 9091 0000 lds r25,(Fsid)+1 + 5502 051a 0196 adiw r24,1 + 5503 051c 9093 0000 sts (Fsid)+1,r25 + 5504 0520 8093 0000 sts Fsid,r24 + 5505 0524 9F83 std Y+7,r25 + 5506 0526 8E83 std Y+6,r24 + 5507 0528 00C0 rjmp .L244 + 5508 .LVL496: + 5509 .L245: + 5510 .LSM445: + 5511 052a 8AE0 ldi r24,lo8(10) + 5512 052c 00C0 rjmp .L241 + 5513 .LVL497: + 5514 .L244: + 5515 052e 80E0 ldi r24,lo8(0) + 5516 0530 00C0 rjmp .L241 + 5517 .LVL498: + 5518 .L250: + 5519 0532 8DE0 ldi r24,lo8(13) + 5520 .LVL499: + 5521 .L241: + 5522 /* epilogue start */ + 5523 .LSM446: + 5524 0534 DF91 pop r29 + 5525 0536 CF91 pop r28 + 5526 .LVL500: + 5527 0538 1F91 pop r17 + 5528 .LVL501: + 5529 053a 0F91 pop r16 + 5530 .LVL502: + 5531 053c FF90 pop r15 + 5532 053e EF90 pop r14 + 5533 .LVL503: + 5534 0540 DF90 pop r13 + 5535 0542 CF90 pop r12 + 5536 0544 BF90 pop r11 + 5537 0546 AF90 pop r10 + 5538 .LVL504: + 5539 0548 9F90 pop r9 + 5540 054a 8F90 pop r8 + 5541 054c 7F90 pop r7 + 5542 054e 6F90 pop r6 + 5543 .LVL505: + 5544 0550 0895 ret + 5545 .LVL506: + 5546 .L256: + 5547 .LSM447: + 5548 0552 C35A subi r28,lo8(-(93)) + 5549 0554 DF4F sbci r29,hi8(-(93)) + 5550 0556 2881 ld r18,Y + 5551 .LVL507: + 5552 0558 30E0 ldi r19,lo8(0) + 5553 055a 40E0 ldi r20,lo8(0) + 5554 055c 50E0 ldi r21,hi8(0) + 5555 055e 522F mov r21,r18 + 5556 0560 4427 clr r20 + 5557 0562 3327 clr r19 + 5558 0564 2227 clr r18 + 5559 0566 8A91 ld r24,-Y + 5560 0568 90E0 ldi r25,lo8(0) + 5561 056a A0E0 ldi r26,lo8(0) + 5562 056c B0E0 ldi r27,hi8(0) + 5563 056e DC01 movw r26,r24 + 5564 0570 9927 clr r25 + 5565 0572 8827 clr r24 + 5566 0574 282B or r18,r24 + 5567 0576 392B or r19,r25 + 5568 0578 4A2B or r20,r26 + 5569 057a 5B2B or r21,r27 + 5570 057c 2297 sbiw r28,2 + 5571 057e 8991 ld r24,Y+ + 5572 0580 90E0 ldi r25,lo8(0) + 5573 0582 A0E0 ldi r26,lo8(0) + 5574 0584 B0E0 ldi r27,hi8(0) + 5575 0586 282B or r18,r24 + 5576 0588 392B or r19,r25 + 5577 058a 4A2B or r20,r26 + 5578 058c 5B2B or r21,r27 + 5579 058e 9881 ld r25,Y + 5580 0590 CB55 subi r28,lo8(-(-91)) + 5581 0592 D040 sbci r29,hi8(-(-91)) + 5582 0594 80E0 ldi r24,lo8(0) + 5583 0596 A0E0 ldi r26,lo8(0) + 5584 0598 B0E0 ldi r27,hi8(0) + 5585 059a 282B or r18,r24 + 5586 059c 392B or r19,r25 + 5587 059e 4A2B or r20,r26 + 5588 05a0 5B2B or r21,r27 + 5589 05a2 2AA3 std Y+34,r18 + 5590 05a4 3BA3 std Y+35,r19 + 5591 05a6 4CA3 std Y+36,r20 + 5592 05a8 5DA3 std Y+37,r21 + 5593 05aa 13E0 ldi r17,lo8(3) + 5594 .LVL508: + 5595 05ac 00C0 rjmp .L258 + 5596 .LFE70: + 5598 .data + 5599 .LC0: + 5600 0000 2022 2A2B .string " \"*+,[=]|\177" + 5600 2C5B 3D5D + 5600 7C7F 00 + 5601 .section .text.f_open,"ax",@progbits + 5602 .global f_open + 5604 f_open: + 5605 .LFB73: + 5606 .LSM448: + 5607 .LVL509: + 5608 0000 2F92 push r2 + 5609 0002 3F92 push r3 + 5610 0004 4F92 push r4 + 5611 0006 5F92 push r5 + 5612 0008 6F92 push r6 + 5613 000a 7F92 push r7 + 5614 000c 8F92 push r8 + 5615 000e 9F92 push r9 + 5616 0010 AF92 push r10 + 5617 0012 BF92 push r11 + 5618 0014 CF92 push r12 + 5619 0016 DF92 push r13 + 5620 0018 EF92 push r14 + 5621 001a FF92 push r15 + 5622 001c 0F93 push r16 + 5623 001e 1F93 push r17 + 5624 0020 DF93 push r29 + 5625 0022 CF93 push r28 + 5626 0024 CDB7 in r28,__SP_L__ + 5627 0026 DEB7 in r29,__SP_H__ + 5628 0028 AD97 sbiw r28,45 + 5629 002a 0FB6 in __tmp_reg__,__SREG__ + 5630 002c F894 cli + 5631 002e DEBF out __SP_H__,r29 + 5632 0030 0FBE out __SREG__,__tmp_reg__ + 5633 0032 CDBF out __SP_L__,r28 + 5634 /* prologue: function */ + 5635 /* frame size = 45 */ + 5636 0034 9DA7 std Y+45,r25 + 5637 0036 8CA7 std Y+44,r24 + 5638 0038 7CA3 std Y+36,r23 + 5639 003a 6BA3 std Y+35,r22 + 5640 .LSM449: + 5641 003c DC01 movw r26,r24 + 5642 003e 1D92 st X+,__zero_reg__ + 5643 0040 1C92 st X,__zero_reg__ + 5644 .LSM450: + 5645 0042 B42F mov r27,r20 + 5646 0044 BF71 andi r27,lo8(31) + 5647 0046 BDA3 std Y+37,r27 + 5648 .LVL510: + 5649 .LSM451: + 5650 0048 4E71 andi r20,lo8(30) + 5651 .LVL511: + 5652 004a CE01 movw r24,r28 + 5653 .LVL512: + 5654 004c 8396 adiw r24,35 + 5655 004e BE01 movw r22,r28 + 5656 .LVL513: + 5657 0050 635F subi r22,lo8(-(13)) + 5658 0052 7F4F sbci r23,hi8(-(13)) + 5659 0054 0E94 0000 call chk_mounted + 5660 .LVL514: + 5661 .LSM452: + 5662 0058 8823 tst r24 + 5663 .LVL515: + 5664 005a 01F0 breq .L261 + 5665 005c 282F mov r18,r24 + 5666 005e 00C0 rjmp .L262 + 5667 .LVL516: + 5668 .L261: + 5669 .LSM453: + 5670 0060 CE01 movw r24,r28 + 5671 .LVL517: + 5672 0062 0196 adiw r24,1 + 5673 0064 9AA3 std Y+34,r25 + 5674 0066 89A3 std Y+33,r24 + 5675 .LSM454: + 5676 0068 EBA0 ldd r14,Y+35 + 5677 006a FCA0 ldd r15,Y+36 + 5678 .LVL518: + 5679 006c 00C0 rjmp .L263 + 5680 .L264: + 5681 .LBB23: + 5682 .LBB24: + 5683 .LSM455: + 5684 006e 0894 sec + 5685 0070 E11C adc r14,__zero_reg__ + 5686 0072 F11C adc r15,__zero_reg__ + 5687 .L263: + 5688 0074 F701 movw r30,r14 + 5689 0076 8081 ld r24,Z + 5690 0078 8032 cpi r24,lo8(32) + 5691 007a 01F0 breq .L264 + 5692 .LSM456: + 5693 007c 8F32 cpi r24,lo8(47) + 5694 007e 01F0 breq .L265 + 5695 0080 8C35 cpi r24,lo8(92) + 5696 0082 01F4 brne .L266 + 5697 .L265: + 5698 .LSM457: + 5699 0084 0894 sec + 5700 0086 E11C adc r14,__zero_reg__ + 5701 0088 F11C adc r15,__zero_reg__ + 5702 .L266: + 5703 .LSM458: + 5704 008a 1B8A std Y+19,__zero_reg__ + 5705 008c 1C8A std Y+20,__zero_reg__ + 5706 008e 1D8A std Y+21,__zero_reg__ + 5707 0090 1E8A std Y+22,__zero_reg__ + 5708 .LSM459: + 5709 0092 D701 movw r26,r14 + 5710 0094 8C91 ld r24,X + 5711 0096 8032 cpi r24,lo8(32) + 5712 0098 00F4 brsh .L267 + 5713 .LBE24: + 5714 .LSM460: + 5715 009a CE01 movw r24,r28 + 5716 009c 0D96 adiw r24,13 + 5717 009e 60E0 ldi r22,lo8(0) + 5718 00a0 70E0 ldi r23,hi8(0) + 5719 00a2 0E94 0000 call dir_seek + 5720 00a6 282F mov r18,r24 + 5721 .LVL519: + 5722 .LBB39: + 5723 .LSM461: + 5724 00a8 18A2 std Y+32,__zero_reg__ + 5725 00aa 1F8E std Y+31,__zero_reg__ + 5726 00ac 00C0 rjmp .L268 + 5727 .LVL520: + 5728 .L267: + 5729 .LBB25: + 5730 .LBB27: + 5731 .LSM462: + 5732 00ae A5E0 ldi r26,lo8(5) + 5733 00b0 3A2E mov r3,r26 + 5734 .LBE27: + 5735 .LBE25: + 5736 .LBB31: + 5737 .LSM463: + 5738 00b2 FDE0 ldi r31,lo8(13) + 5739 00b4 4F2E mov r4,r31 + 5740 00b6 512C mov r5,__zero_reg__ + 5741 00b8 4C0E add r4,r28 + 5742 00ba 5D1E adc r5,r29 + 5743 .LVL521: + 5744 .L320: + 5745 .LBE31: + 5746 .LBB36: + 5747 .LBB26: + 5748 .LSM464: + 5749 00bc 09A1 ldd r16,Y+33 + 5750 00be 1AA1 ldd r17,Y+34 + 5751 .LSM465: + 5752 00c0 C801 movw r24,r16 + 5753 00c2 60E2 ldi r22,lo8(32) + 5754 00c4 70E0 ldi r23,hi8(32) + 5755 00c6 4BE0 ldi r20,lo8(11) + 5756 00c8 50E0 ldi r21,hi8(11) + 5757 00ca 0E94 0000 call mem_set + 5758 .LVL522: + 5759 00ce 40E0 ldi r20,lo8(0) + 5760 00d0 50E0 ldi r21,hi8(0) + 5761 .LVL523: + 5762 00d2 CC24 clr r12 + 5763 00d4 DD24 clr r13 + 5764 00d6 E8E0 ldi r30,lo8(8) + 5765 00d8 AE2E mov r10,r30 + 5766 00da B12C mov r11,__zero_reg__ + 5767 00dc A0E0 ldi r26,lo8(0) + 5768 .LVL524: + 5769 .L319: + 5770 .LSM466: + 5771 00de F701 movw r30,r14 + 5772 00e0 EC0D add r30,r12 + 5773 00e2 FD1D adc r31,r13 + 5774 00e4 2081 ld r18,Z + 5775 00e6 0894 sec + 5776 00e8 C11C adc r12,__zero_reg__ + 5777 00ea D11C adc r13,__zero_reg__ + 5778 .LSM467: + 5779 00ec 2132 cpi r18,lo8(33) + 5780 00ee 00F4 brsh .+2 + 5781 00f0 00C0 rjmp .L269 + 5782 00f2 2F32 cpi r18,lo8(47) + 5783 00f4 01F4 brne .+2 + 5784 00f6 00C0 rjmp .L270 + 5785 00f8 2C35 cpi r18,lo8(92) + 5786 00fa 01F4 brne .+2 + 5787 00fc 00C0 rjmp .L270 + 5788 .LSM468: + 5789 00fe 2E32 cpi r18,lo8(46) + 5790 0100 01F0 breq .L271 + 5791 0102 4A15 cp r20,r10 + 5792 0104 5B05 cpc r21,r11 + 5793 0106 04F0 brlt .L272 + 5794 .L271: + 5795 .LSM469: + 5796 0108 B8E0 ldi r27,lo8(8) + 5797 010a AB16 cp r10,r27 + 5798 010c B104 cpc r11,__zero_reg__ + 5799 010e 01F0 breq .+2 + 5800 0110 00C0 rjmp .L273 + 5801 0112 2E32 cpi r18,lo8(46) + 5802 0114 01F0 breq .+2 + 5803 0116 00C0 rjmp .L273 + 5804 .LSM470: + 5805 0118 AA0F lsl r26 + 5806 011a AA0F lsl r26 + 5807 011c 48E0 ldi r20,lo8(8) + 5808 011e 50E0 ldi r21,hi8(8) + 5809 0120 7BE0 ldi r23,lo8(11) + 5810 0122 A72E mov r10,r23 + 5811 0124 B12C mov r11,__zero_reg__ + 5812 0126 00C0 rjmp .L319 + 5813 .L272: + 5814 .LSM471: + 5815 0128 27FD sbrc r18,7 + 5816 .LSM472: + 5817 012a A360 ori r26,lo8(3) + 5818 .L275: + 5819 .LSM473: + 5820 012c 822F mov r24,r18 + 5821 012e 8158 subi r24,lo8(-(127)) + 5822 0130 8F31 cpi r24,lo8(31) + 5823 0132 00F0 brlo .L276 + 5824 0134 8F55 subi r24,lo8(-(-95)) + 5825 0136 8D31 cpi r24,lo8(29) + 5826 0138 00F4 brsh .L277 + 5827 .L276: + 5828 .LSM474: + 5829 013a F701 movw r30,r14 + 5830 013c EC0D add r30,r12 + 5831 013e FD1D adc r31,r13 + 5832 0140 3081 ld r19,Z + 5833 .LSM475: + 5834 0142 832F mov r24,r19 + 5835 0144 8054 subi r24,lo8(-(-64)) + 5836 0146 8F33 cpi r24,lo8(63) + 5837 0148 00F0 brlo .L278 + 5838 014a 8054 subi r24,lo8(-(-64)) + 5839 014c 8D37 cpi r24,lo8(125) + 5840 014e 00F0 brlo .+2 + 5841 0150 00C0 rjmp .L273 + 5842 .L278: + 5843 0152 C501 movw r24,r10 + 5844 0154 0197 sbiw r24,1 + 5845 0156 4817 cp r20,r24 + 5846 0158 5907 cpc r21,r25 + 5847 015a 04F0 brlt .+2 + 5848 015c 00C0 rjmp .L273 + 5849 .LSM476: + 5850 015e 0894 sec + 5851 0160 C11C adc r12,__zero_reg__ + 5852 0162 D11C adc r13,__zero_reg__ + 5853 .LSM477: + 5854 0164 F801 movw r30,r16 + 5855 0166 E40F add r30,r20 + 5856 0168 F51F adc r31,r21 + 5857 016a 2083 st Z,r18 + 5858 016c CA01 movw r24,r20 + 5859 016e 0196 adiw r24,1 + 5860 .LVL525: + 5861 .LSM478: + 5862 0170 F801 movw r30,r16 + 5863 0172 E80F add r30,r24 + 5864 0174 F91F adc r31,r25 + 5865 0176 3083 st Z,r19 + 5866 0178 AC01 movw r20,r24 + 5867 017a 00C0 rjmp .L321 + 5868 .LVL526: + 5869 .L277: + 5870 .LSM479: + 5871 017c 622F mov r22,r18 + 5872 017e 70E0 ldi r23,lo8(0) + 5873 0180 E0E0 ldi r30,lo8(.LC0) + 5874 0182 F0E0 ldi r31,hi8(.LC0) + 5875 .LVL527: + 5876 0184 00C0 rjmp .L279 + 5877 .L281: + 5878 .LBB28: + 5879 .LBB29: + 5880 .LSM480: + 5881 0186 3196 adiw r30,1 + 5882 .L279: + 5883 0188 8081 ld r24,Z + 5884 018a 8823 tst r24 + 5885 018c 01F0 breq .L280 + 5886 018e 90E0 ldi r25,lo8(0) + 5887 0190 8617 cp r24,r22 + 5888 0192 9707 cpc r25,r23 + 5889 0194 01F4 brne .L281 + 5890 0196 00C0 rjmp .L273 + 5891 .L280: + 5892 .LBE29: + 5893 .LBE28: + 5894 .LSM481: + 5895 0198 822F mov r24,r18 + 5896 019a 8154 subi r24,lo8(-(-65)) + 5897 019c 8A31 cpi r24,lo8(26) + 5898 019e 00F4 brsh .L282 + 5899 .LSM482: + 5900 01a0 A260 ori r26,lo8(2) + 5901 01a2 00C0 rjmp .L283 + 5902 .L282: + 5903 .LSM483: + 5904 01a4 822F mov r24,r18 + 5905 01a6 8156 subi r24,lo8(-(-97)) + 5906 01a8 8A31 cpi r24,lo8(26) + 5907 01aa 00F4 brsh .L283 + 5908 .LSM484: + 5909 01ac A160 ori r26,lo8(1) + 5910 01ae 2052 subi r18,lo8(-(-32)) + 5911 .L283: + 5912 .LSM485: + 5913 01b0 F801 movw r30,r16 + 5914 .LVL528: + 5915 01b2 E40F add r30,r20 + 5916 01b4 F51F adc r31,r21 + 5917 01b6 2083 st Z,r18 + 5918 .LVL529: + 5919 .L321: + 5920 01b8 4F5F subi r20,lo8(-(1)) + 5921 01ba 5F4F sbci r21,hi8(-(1)) + 5922 01bc 00C0 rjmp .L319 + 5923 .L269: + 5924 01be 9A2F mov r25,r26 + 5925 01c0 64E0 ldi r22,lo8(4) + 5926 .LVL530: + 5927 .L313: + 5928 .LSM486: + 5929 01c2 452B or r20,r21 + 5930 01c4 01F4 brne .+2 + 5931 01c6 00C0 rjmp .L273 + 5932 .LSM487: + 5933 01c8 F801 movw r30,r16 + 5934 01ca 8081 ld r24,Z + 5935 01cc 853E cpi r24,lo8(-27) + 5936 01ce 01F4 brne .L284 + 5937 01d0 3082 st Z,r3 + 5938 .L284: + 5939 .LSM488: + 5940 01d2 F8E0 ldi r31,lo8(8) + 5941 01d4 AF16 cp r10,r31 + 5942 01d6 B104 cpc r11,__zero_reg__ + 5943 01d8 01F4 brne .L285 + 5944 01da 9A2F mov r25,r26 + 5945 01dc 990F lsl r25 + 5946 01de 990F lsl r25 + 5947 .LVL531: + 5948 .L285: + 5949 .LSM489: + 5950 01e0 292F mov r18,r25 + 5951 01e2 30E0 ldi r19,lo8(0) + 5952 .LVL532: + 5953 01e4 C901 movw r24,r18 + 5954 01e6 8370 andi r24,lo8(3) + 5955 01e8 9070 andi r25,hi8(3) + 5956 01ea 0197 sbiw r24,1 + 5957 01ec 01F4 brne .L286 + 5958 01ee 6061 ori r22,lo8(16) + 5959 .L286: + 5960 .LSM490: + 5961 01f0 2C70 andi r18,lo8(12) + 5962 01f2 3070 andi r19,hi8(12) + 5963 01f4 2430 cpi r18,4 + 5964 01f6 3105 cpc r19,__zero_reg__ + 5965 01f8 01F4 brne .L287 + 5966 01fa 6860 ori r22,lo8(8) + 5967 .L287: + 5968 .LSM491: + 5969 01fc D801 movw r26,r16 + 5970 01fe 1B96 adiw r26,11 + 5971 0200 6C93 st X,r22 + 5972 .LBE26: + 5973 .LBE36: + 5974 .LBB37: + 5975 .LSM492: + 5976 0202 C201 movw r24,r4 + 5977 0204 60E0 ldi r22,lo8(0) + 5978 0206 70E0 ldi r23,hi8(0) + 5979 .LVL533: + 5980 0208 0E94 0000 call dir_seek + 5981 .LVL534: + 5982 .L322: + 5983 020c 482F mov r20,r24 + 5984 .LVL535: + 5985 .LBB32: + 5986 .LSM493: + 5987 020e 8823 tst r24 + 5988 0210 01F4 brne .L288 + 5989 .LVL536: + 5990 .LBE32: + 5991 .LSM494: + 5992 0212 4B8D ldd r20,Y+27 + 5993 0214 5C8D ldd r21,Y+28 + 5994 0216 6D8D ldd r22,Y+29 + 5995 0218 7E8D ldd r23,Y+30 + 5996 021a 8D85 ldd r24,Y+13 + 5997 021c 9E85 ldd r25,Y+14 + 5998 .LVL537: + 5999 021e 0E94 0000 call move_window + 6000 0222 482F mov r20,r24 + 6001 .LVL538: + 6002 .LBB35: + 6003 .LSM495: + 6004 0224 8823 tst r24 + 6005 0226 01F4 brne .L288 + 6006 .LVL539: + 6007 .LSM496: + 6008 0228 EF8D ldd r30,Y+31 + 6009 022a F8A1 ldd r31,Y+32 + 6010 .LVL540: + 6011 .LSM497: + 6012 022c 8081 ld r24,Z + 6013 .LVL541: + 6014 022e 8823 tst r24 + 6015 0230 01F4 brne .L289 + 6016 0232 44E0 ldi r20,lo8(4) + 6017 0234 00C0 rjmp .L288 + 6018 .L289: + 6019 .LSM498: + 6020 0236 8385 ldd r24,Z+11 + 6021 0238 83FD sbrc r24,3 + 6022 023a 00C0 rjmp .L290 + 6023 023c 89A1 ldd r24,Y+33 + 6024 .LVL542: + 6025 023e 9AA1 ldd r25,Y+34 + 6026 .LVL543: + 6027 0240 9C01 movw r18,r24 + 6028 .LVL544: + 6029 0242 D901 movw r26,r18 + 6030 .LVL545: + 6031 0244 2BE0 ldi r18,lo8(11) + 6032 0246 30E0 ldi r19,hi8(11) + 6033 .LVL546: + 6034 .L291: + 6035 .LBB33: + 6036 .LBB34: + 6037 .LSM499: + 6038 0248 2150 subi r18,lo8(-(-1)) + 6039 024a 3040 sbci r19,hi8(-(-1)) + 6040 024c 8FEF ldi r24,hi8(-1) + 6041 024e 2F3F cpi r18,lo8(-1) + 6042 0250 3807 cpc r19,r24 + 6043 0252 01F0 breq .L288 + 6044 0254 9081 ld r25,Z + 6045 .LVL547: + 6046 0256 8C91 ld r24,X + 6047 0258 9817 cp r25,r24 + 6048 025a 01F4 brne .L290 + 6049 025c 3196 adiw r30,1 + 6050 .LVL548: + 6051 025e 1196 adiw r26,1 + 6052 0260 00C0 rjmp .L291 + 6053 .LVL549: + 6054 .L290: + 6055 .LBE34: + 6056 .LBE33: + 6057 .LBE35: + 6058 .LSM500: + 6059 0262 C201 movw r24,r4 + 6060 0264 60E0 ldi r22,lo8(0) + 6061 0266 0E94 0000 call dir_next + 6062 .LVL550: + 6063 026a 00C0 rjmp .L322 + 6064 .LVL551: + 6065 .L288: + 6066 .LBE37: + 6067 .LSM501: + 6068 026c E9A1 ldd r30,Y+33 + 6069 026e FAA1 ldd r31,Y+34 + 6070 .LVL552: + 6071 0270 8385 ldd r24,Z+11 + 6072 .LVL553: + 6073 0272 8470 andi r24,lo8(4) + 6074 .LSM502: + 6075 0274 4423 tst r20 + 6076 0276 01F0 breq .L293 + 6077 0278 242F mov r18,r20 + 6078 .LVL554: + 6079 .LSM503: + 6080 027a 4430 cpi r20,lo8(4) + 6081 027c 01F4 brne .L294 + 6082 027e 8823 tst r24 + 6083 0280 01F0 breq .L295 + 6084 0282 00C0 rjmp .L268 + 6085 .LVL555: + 6086 .L293: + 6087 .LSM504: + 6088 0284 8823 tst r24 + 6089 0286 01F4 brne .L294 + 6090 .LSM505: + 6091 0288 EF8D ldd r30,Y+31 + 6092 028a F8A1 ldd r31,Y+32 + 6093 .LVL556: + 6094 .LSM506: + 6095 028c 8385 ldd r24,Z+11 + 6096 .LVL557: + 6097 028e 84FF sbrs r24,4 + 6098 0290 00C0 rjmp .L295 + 6099 .LBB38: + 6100 .LBB30: + 6101 .LSM507: + 6102 0292 EC0C add r14,r12 + 6103 0294 FD1C adc r15,r13 + 6104 .LBE30: + 6105 .LBE38: + 6106 .LSM508: + 6107 0296 7588 ldd r7,Z+21 + 6108 0298 6624 clr r6 + 6109 029a 2489 ldd r18,Z+20 + 6110 .LVL558: + 6111 029c 30E0 ldi r19,lo8(0) + 6112 029e 2629 or r18,r6 + 6113 02a0 3729 or r19,r7 + 6114 02a2 40E0 ldi r20,lo8(0) + 6115 02a4 50E0 ldi r21,hi8(0) + 6116 .LVL559: + 6117 02a6 A901 movw r20,r18 + 6118 02a8 3327 clr r19 + 6119 02aa 2227 clr r18 + 6120 02ac 938C ldd r9,Z+27 + 6121 02ae 8824 clr r8 + 6122 02b0 828D ldd r24,Z+26 + 6123 02b2 90E0 ldi r25,lo8(0) + 6124 .LVL560: + 6125 02b4 8829 or r24,r8 + 6126 02b6 9929 or r25,r9 + 6127 02b8 A0E0 ldi r26,lo8(0) + 6128 02ba B0E0 ldi r27,hi8(0) + 6129 .LVL561: + 6130 02bc 282B or r18,r24 + 6131 02be 392B or r19,r25 + 6132 02c0 4A2B or r20,r26 + 6133 02c2 5B2B or r21,r27 + 6134 02c4 2B8B std Y+19,r18 + 6135 02c6 3C8B std Y+20,r19 + 6136 02c8 4D8B std Y+21,r20 + 6137 02ca 5E8B std Y+22,r21 + 6138 02cc 00C0 rjmp .L320 + 6139 .LVL562: + 6140 .L273: + 6141 02ce 26E0 ldi r18,lo8(6) + 6142 .LVL563: + 6143 02d0 00C0 rjmp .L268 + 6144 .LVL564: + 6145 .L294: + 6146 02d2 242F mov r18,r20 + 6147 .LVL565: + 6148 02d4 00C0 rjmp .L268 + 6149 .LVL566: + 6150 .L295: + 6151 02d6 25E0 ldi r18,lo8(5) + 6152 .LVL567: + 6153 .L268: + 6154 .LBE39: + 6155 .LBE23: + 6156 .LSM509: + 6157 02d8 9DA1 ldd r25,Y+37 + 6158 .LVL568: + 6159 02da 492F mov r20,r25 + 6160 .LVL569: + 6161 02dc 50E0 ldi r21,lo8(0) + 6162 02de CA01 movw r24,r20 + 6163 .LVL570: + 6164 02e0 8C71 andi r24,lo8(28) + 6165 02e2 9070 andi r25,hi8(28) + 6166 02e4 892B or r24,r25 + 6167 02e6 01F4 brne .+2 + 6168 02e8 00C0 rjmp .L296 + 6169 .LBB40: + 6170 .LSM510: + 6171 02ea 2223 tst r18 + 6172 02ec 01F4 brne .+2 + 6173 02ee 00C0 rjmp .L297 + 6174 .LSM511: + 6175 02f0 2430 cpi r18,lo8(4) + 6176 02f2 01F0 breq .+2 + 6177 02f4 00C0 rjmp .L262 + 6178 .LBB45: + 6179 .LSM512: + 6180 02f6 8E01 movw r16,r28 + 6181 .LVL571: + 6182 02f8 035F subi r16,lo8(-(13)) + 6183 02fa 1F4F sbci r17,hi8(-(13)) + 6184 02fc C801 movw r24,r16 + 6185 02fe 60E0 ldi r22,lo8(0) + 6186 0300 70E0 ldi r23,hi8(0) + 6187 .LVL572: + 6188 0302 0E94 0000 call dir_seek + 6189 .LVL573: + 6190 0306 282F mov r18,r24 + 6191 .LVL574: + 6192 .LBB48: + 6193 .LSM513: + 6194 0308 8823 tst r24 + 6195 030a 01F0 breq .+2 + 6196 030c 00C0 rjmp .L262 + 6197 .LVL575: + 6198 .L315: + 6199 .LBE48: + 6200 .LSM514: + 6201 030e 4B8D ldd r20,Y+27 + 6202 0310 5C8D ldd r21,Y+28 + 6203 0312 6D8D ldd r22,Y+29 + 6204 0314 7E8D ldd r23,Y+30 + 6205 0316 8D85 ldd r24,Y+13 + 6206 0318 9E85 ldd r25,Y+14 + 6207 .LVL576: + 6208 031a 0E94 0000 call move_window + 6209 .LVL577: + 6210 031e 282F mov r18,r24 + 6211 .LVL578: + 6212 .LBB47: + 6213 .LSM515: + 6214 0320 8823 tst r24 + 6215 0322 01F0 breq .+2 + 6216 0324 00C0 rjmp .L262 + 6217 .LVL579: + 6218 .LSM516: + 6219 0326 EF8D ldd r30,Y+31 + 6220 0328 F8A1 ldd r31,Y+32 + 6221 032a E081 ld r30,Z + 6222 .LVL580: + 6223 .LSM517: + 6224 032c E53E cpi r30,lo8(-27) + 6225 032e 01F4 brne .+2 + 6226 0330 00C0 rjmp .L298 + 6227 0332 EE23 tst r30 + 6228 0334 01F4 brne .+2 + 6229 0336 00C0 rjmp .L298 + 6230 .LBE47: + 6231 .LSM518: + 6232 0338 C801 movw r24,r16 + 6233 .LVL581: + 6234 033a 61E0 ldi r22,lo8(1) + 6235 033c 0E94 0000 call dir_next + 6236 .LVL582: + 6237 0340 282F mov r18,r24 + 6238 .LVL583: + 6239 .LBB46: + 6240 .LSM519: + 6241 0342 8823 tst r24 + 6242 0344 01F0 breq .L315 + 6243 .LVL584: + 6244 0346 00C0 rjmp .L262 + 6245 .L323: + 6246 .LSM520: + 6247 0348 0F8D ldd r16,Y+31 + 6248 034a 18A1 ldd r17,Y+32 + 6249 .LVL585: + 6250 .LSM521: + 6251 034c C801 movw r24,r16 + 6252 .LVL586: + 6253 034e 60E0 ldi r22,lo8(0) + 6254 0350 70E0 ldi r23,hi8(0) + 6255 0352 40E2 ldi r20,lo8(32) + 6256 0354 50E0 ldi r21,hi8(32) + 6257 0356 0E94 0000 call mem_set + 6258 .LVL587: + 6259 .LSM522: + 6260 035a 69A1 ldd r22,Y+33 + 6261 035c 7AA1 ldd r23,Y+34 + 6262 035e C801 movw r24,r16 + 6263 0360 4BE0 ldi r20,lo8(11) + 6264 0362 50E0 ldi r21,hi8(11) + 6265 0364 0E94 0000 call mem_cpy + 6266 .LSM523: + 6267 0368 E9A1 ldd r30,Y+33 + 6268 036a FAA1 ldd r31,Y+34 + 6269 036c 8385 ldd r24,Z+11 + 6270 036e 8871 andi r24,lo8(24) + 6271 0370 D801 movw r26,r16 + 6272 0372 1C96 adiw r26,12 + 6273 0374 8C93 st X,r24 + 6274 .LSM524: + 6275 0376 ED85 ldd r30,Y+13 + 6276 0378 FE85 ldd r31,Y+14 + 6277 037a 81E0 ldi r24,lo8(1) + 6278 037c 8483 std Z+4,r24 + 6279 .LBE46: + 6280 .LBE45: + 6281 .LSM525: + 6282 037e BDA1 ldd r27,Y+37 + 6283 0380 B860 ori r27,lo8(8) + 6284 0382 BDA3 std Y+37,r27 + 6285 .LVL588: + 6286 .LSM526: + 6287 0384 EF8C ldd r14,Y+31 + 6288 0386 F8A0 ldd r15,Y+32 + 6289 .LVL589: + 6290 0388 00C0 rjmp .L300 + 6291 .LVL590: + 6292 .L297: + 6293 .LSM527: + 6294 038a 42FF sbrs r20,2 + 6295 038c 00C0 rjmp .L301 + 6296 038e 28E0 ldi r18,lo8(8) + 6297 0390 00C0 rjmp .L262 + 6298 .L301: + 6299 .LSM528: + 6300 0392 EF8C ldd r14,Y+31 + 6301 0394 F8A0 ldd r15,Y+32 + 6302 .LVL591: + 6303 .LSM529: + 6304 0396 E114 cp r14,__zero_reg__ + 6305 0398 F104 cpc r15,__zero_reg__ + 6306 039a 01F4 brne .+2 + 6307 039c 00C0 rjmp .L302 + 6308 039e F701 movw r30,r14 + 6309 .LVL592: + 6310 03a0 8385 ldd r24,Z+11 + 6311 03a2 8171 andi r24,lo8(17) + 6312 03a4 01F0 breq .+2 + 6313 03a6 00C0 rjmp .L302 + 6314 .LSM530: + 6315 03a8 43FF sbrs r20,3 + 6316 03aa 00C0 rjmp .L300 + 6317 .LSM531: + 6318 03ac 9589 ldd r25,Z+21 + 6319 03ae 80E0 ldi r24,lo8(0) + 6320 03b0 2489 ldd r18,Z+20 + 6321 .LVL593: + 6322 03b2 30E0 ldi r19,lo8(0) + 6323 .LVL594: + 6324 03b4 822B or r24,r18 + 6325 03b6 932B or r25,r19 + 6326 03b8 A0E0 ldi r26,lo8(0) + 6327 03ba B0E0 ldi r27,hi8(0) + 6328 .LVL595: + 6329 03bc 2C01 movw r4,r24 + 6330 03be 3324 clr r3 + 6331 03c0 2224 clr r2 + 6332 .LVL596: + 6333 03c2 938D ldd r25,Z+27 + 6334 03c4 80E0 ldi r24,lo8(0) + 6335 03c6 228D ldd r18,Z+26 + 6336 03c8 30E0 ldi r19,lo8(0) + 6337 03ca 822B or r24,r18 + 6338 03cc 932B or r25,r19 + 6339 03ce A0E0 ldi r26,lo8(0) + 6340 03d0 B0E0 ldi r27,hi8(0) + 6341 03d2 282A or r2,r24 + 6342 03d4 392A or r3,r25 + 6343 03d6 4A2A or r4,r26 + 6344 03d8 5B2A or r5,r27 + 6345 .LSM532: + 6346 03da 148A std Z+20,__zero_reg__ + 6347 03dc 158A std Z+21,__zero_reg__ + 6348 .LSM533: + 6349 03de 128E std Z+26,__zero_reg__ + 6350 03e0 138E std Z+27,__zero_reg__ + 6351 .LSM534: + 6352 03e2 148E std Z+28,__zero_reg__ + 6353 03e4 158E std Z+29,__zero_reg__ + 6354 03e6 168E std Z+30,__zero_reg__ + 6355 03e8 178E std Z+31,__zero_reg__ + 6356 .LSM535: + 6357 03ea 8D85 ldd r24,Y+13 + 6358 03ec 9E85 ldd r25,Y+14 + 6359 03ee 9BA7 std Y+43,r25 + 6360 03f0 8AA7 std Y+42,r24 + 6361 03f2 81E0 ldi r24,lo8(1) + 6362 03f4 AAA5 ldd r26,Y+42 + 6363 03f6 BBA5 ldd r27,Y+43 + 6364 03f8 1496 adiw r26,4 + 6365 03fa 8C93 st X,r24 + 6366 .LSM536: + 6367 03fc AAA5 ldd r26,Y+42 + 6368 03fe BBA5 ldd r27,Y+43 + 6369 0400 9A96 adiw r26,42 + 6370 0402 8D91 ld r24,X+ + 6371 0404 9D91 ld r25,X+ + 6372 0406 0D90 ld __tmp_reg__,X+ + 6373 0408 BC91 ld r27,X + 6374 040a A02D mov r26,__tmp_reg__ + 6375 040c 8EA3 std Y+38,r24 + 6376 040e 9FA3 std Y+39,r25 + 6377 0410 A8A7 std Y+40,r26 + 6378 0412 B9A7 std Y+41,r27 + 6379 .LVL597: + 6380 .LSM537: + 6381 0414 2114 cp r2,__zero_reg__ + 6382 0416 3104 cpc r3,__zero_reg__ + 6383 0418 4104 cpc r4,__zero_reg__ + 6384 041a 5104 cpc r5,__zero_reg__ + 6385 041c 01F4 brne .+2 + 6386 041e 00C0 rjmp .L303 + 6387 .LBB41: + 6388 .LBB42: + 6389 .LSM538: + 6390 0420 B1E0 ldi r27,lo8(1) + 6391 0422 2B16 cp r2,r27 + 6392 0424 3104 cpc r3,__zero_reg__ + 6393 0426 4104 cpc r4,__zero_reg__ + 6394 0428 5104 cpc r5,__zero_reg__ + 6395 042a 01F4 brne .+2 + 6396 042c 00C0 rjmp .L304 + 6397 042e EAA5 ldd r30,Y+42 + 6398 0430 FBA5 ldd r31,Y+43 + 6399 0432 828D ldd r24,Z+26 + 6400 0434 938D ldd r25,Z+27 + 6401 0436 A48D ldd r26,Z+28 + 6402 0438 B58D ldd r27,Z+29 + 6403 043a 2816 cp r2,r24 + 6404 043c 3906 cpc r3,r25 + 6405 043e 4A06 cpc r4,r26 + 6406 0440 5B06 cpc r5,r27 + 6407 0442 00F0 brlo .+2 + 6408 0444 00C0 rjmp .L304 + 6409 0446 6201 movw r12,r4 + 6410 0448 5101 movw r10,r2 + 6411 .LVL598: + 6412 044a 00C0 rjmp .L305 + 6413 .LVL599: + 6414 .L309: + 6415 .LBE42: + 6416 .LSM539: + 6417 044c 8AA5 ldd r24,Y+42 + 6418 044e 9BA5 ldd r25,Y+43 + 6419 0450 B601 movw r22,r12 + 6420 0452 A501 movw r20,r10 + 6421 0454 0E94 0000 call get_fat + 6422 .LVL600: + 6423 0458 3B01 movw r6,r22 + 6424 045a 4C01 movw r8,r24 + 6425 .LVL601: + 6426 .LBB43: + 6427 .LSM540: + 6428 045c 6115 cp r22,__zero_reg__ + 6429 045e 7105 cpc r23,__zero_reg__ + 6430 0460 8105 cpc r24,__zero_reg__ + 6431 0462 9105 cpc r25,__zero_reg__ + 6432 0464 01F4 brne .+2 + 6433 0466 00C0 rjmp .L306 + 6434 .LVL602: + 6435 .LSM541: + 6436 0468 6130 cpi r22,lo8(1) + 6437 046a 7105 cpc r23,__zero_reg__ + 6438 046c 8105 cpc r24,__zero_reg__ + 6439 046e 9105 cpc r25,__zero_reg__ + 6440 0470 01F4 brne .+2 + 6441 0472 00C0 rjmp .L304 + 6442 .LSM542: + 6443 0474 6F3F cpi r22,lo8(-1) + 6444 0476 2FEF ldi r18,hi8(-1) + 6445 0478 7207 cpc r23,r18 + 6446 047a 2FEF ldi r18,hlo8(-1) + 6447 047c 8207 cpc r24,r18 + 6448 047e 2FEF ldi r18,hhi8(-1) + 6449 0480 9207 cpc r25,r18 + 6450 0482 01F4 brne .L307 + 6451 0484 21E0 ldi r18,lo8(1) + 6452 .LVL603: + 6453 0486 00C0 rjmp .L262 + 6454 .LVL604: + 6455 .L307: + 6456 .LBE43: + 6457 .LSM543: + 6458 0488 8AA5 ldd r24,Y+42 + 6459 048a 9BA5 ldd r25,Y+43 + 6460 048c B601 movw r22,r12 + 6461 048e A501 movw r20,r10 + 6462 0490 00E0 ldi r16,lo8(0) + 6463 0492 10E0 ldi r17,hi8(0) + 6464 0494 20E0 ldi r18,hlo8(0) + 6465 0496 30E0 ldi r19,hhi8(0) + 6466 .LVL605: + 6467 0498 0E94 0000 call put_fat + 6468 .LVL606: + 6469 049c 282F mov r18,r24 + 6470 .LVL607: + 6471 .LBB44: + 6472 .LSM544: + 6473 049e 8823 tst r24 + 6474 04a0 01F0 breq .+2 + 6475 04a2 00C0 rjmp .L262 + 6476 .LVL608: + 6477 .LSM545: + 6478 04a4 EAA5 ldd r30,Y+42 + 6479 04a6 FBA5 ldd r31,Y+43 + 6480 04a8 8685 ldd r24,Z+14 + 6481 04aa 9785 ldd r25,Z+15 + 6482 04ac A089 ldd r26,Z+16 + 6483 04ae B189 ldd r27,Z+17 + 6484 .LVL609: + 6485 04b0 8F3F cpi r24,lo8(-1) + 6486 04b2 FFEF ldi r31,hi8(-1) + 6487 04b4 9F07 cpc r25,r31 + 6488 04b6 FFEF ldi r31,hlo8(-1) + 6489 04b8 AF07 cpc r26,r31 + 6490 04ba FFEF ldi r31,hhi8(-1) + 6491 04bc BF07 cpc r27,r31 + 6492 04be 01F0 breq .L308 + 6493 .LSM546: + 6494 04c0 0196 adiw r24,1 + 6495 04c2 A11D adc r26,__zero_reg__ + 6496 04c4 B11D adc r27,__zero_reg__ + 6497 04c6 EAA5 ldd r30,Y+42 + 6498 04c8 FBA5 ldd r31,Y+43 + 6499 04ca 8687 std Z+14,r24 + 6500 04cc 9787 std Z+15,r25 + 6501 04ce A08B std Z+16,r26 + 6502 04d0 B18B std Z+17,r27 + 6503 .LSM547: + 6504 04d2 21E0 ldi r18,lo8(1) + 6505 .LVL610: + 6506 04d4 2583 std Z+5,r18 + 6507 .LVL611: + 6508 .L308: + 6509 04d6 6401 movw r12,r8 + 6510 04d8 5301 movw r10,r6 + 6511 .LVL612: + 6512 .L305: + 6513 .LSM548: + 6514 04da EAA5 ldd r30,Y+42 + 6515 04dc FBA5 ldd r31,Y+43 + 6516 04de 828D ldd r24,Z+26 + 6517 04e0 938D ldd r25,Z+27 + 6518 04e2 A48D ldd r26,Z+28 + 6519 04e4 B58D ldd r27,Z+29 + 6520 04e6 A816 cp r10,r24 + 6521 04e8 B906 cpc r11,r25 + 6522 04ea CA06 cpc r12,r26 + 6523 04ec DB06 cpc r13,r27 + 6524 04ee 00F4 brsh .+2 + 6525 04f0 00C0 rjmp .L309 + 6526 04f2 00C0 rjmp .L306 + 6527 .LVL613: + 6528 .L304: + 6529 04f4 22E0 ldi r18,lo8(2) + 6530 .LVL614: + 6531 04f6 00C0 rjmp .L262 + 6532 .LVL615: + 6533 .L303: + 6534 .LBE44: + 6535 .LBE41: + 6536 .LSM549: + 6537 04f8 8D85 ldd r24,Y+13 + 6538 04fa 9E85 ldd r25,Y+14 + 6539 04fc 4EA1 ldd r20,Y+38 + 6540 04fe 5FA1 ldd r21,Y+39 + 6541 0500 68A5 ldd r22,Y+40 + 6542 0502 79A5 ldd r23,Y+41 + 6543 0504 0E94 0000 call move_window + 6544 .LVL616: + 6545 0508 282F mov r18,r24 + 6546 .LVL617: + 6547 .LSM550: + 6548 050a 8823 tst r24 + 6549 050c 01F0 breq .+2 + 6550 050e 00C0 rjmp .L262 + 6551 .LVL618: + 6552 .L300: + 6553 .LSM551: + 6554 0510 FDA1 ldd r31,Y+37 + 6555 0512 F3FF sbrs r31,3 + 6556 0514 00C0 rjmp .L310 + 6557 .LSM552: + 6558 0516 D701 movw r26,r14 + 6559 .LVL619: + 6560 0518 1B96 adiw r26,11 + 6561 051a 1C92 st X,__zero_reg__ + 6562 .LSM553: + 6563 051c 0E94 0000 call get_fattime + 6564 .LVL620: + 6565 .LSM554: + 6566 0520 F701 movw r30,r14 + 6567 0522 6687 std Z+14,r22 + 6568 0524 272F mov r18,r23 + 6569 0526 3327 clr r19 + 6570 0528 2787 std Z+15,r18 + 6571 052a 9C01 movw r18,r24 + 6572 052c 4427 clr r20 + 6573 052e 5527 clr r21 + 6574 0530 208B std Z+16,r18 + 6575 0532 692F mov r22,r25 + 6576 0534 7727 clr r23 + 6577 0536 8827 clr r24 + 6578 0538 9927 clr r25 + 6579 053a 618B std Z+17,r22 + 6580 .LSM555: + 6581 053c ED85 ldd r30,Y+13 + 6582 053e FE85 ldd r31,Y+14 + 6583 0540 81E0 ldi r24,lo8(1) + 6584 0542 8483 std Z+4,r24 + 6585 .LSM556: + 6586 0544 FDA1 ldd r31,Y+37 + 6587 0546 F062 ori r31,lo8(32) + 6588 0548 FDA3 std Y+37,r31 + 6589 .LVL621: + 6590 054a 00C0 rjmp .L310 + 6591 .LVL622: + 6592 .L296: + 6593 .LBE40: + 6594 .LSM557: + 6595 054c 2223 tst r18 + 6596 054e 01F0 breq .+2 + 6597 0550 00C0 rjmp .L262 + 6598 .LSM558: + 6599 0552 EF8C ldd r14,Y+31 + 6600 0554 F8A0 ldd r15,Y+32 + 6601 .LVL623: + 6602 .LSM559: + 6603 0556 E114 cp r14,__zero_reg__ + 6604 0558 F104 cpc r15,__zero_reg__ + 6605 055a 01F4 brne .+2 + 6606 055c 00C0 rjmp .L311 + 6607 055e D701 movw r26,r14 + 6608 .LVL624: + 6609 0560 1B96 adiw r26,11 + 6610 0562 8C91 ld r24,X + 6611 0564 84FD sbrc r24,4 + 6612 0566 00C0 rjmp .L311 + 6613 .LSM560: + 6614 0568 41FF sbrs r20,1 + 6615 056a 00C0 rjmp .L310 + 6616 056c 80FD sbrc r24,0 + 6617 056e 00C0 rjmp .L302 + 6618 .LVL625: + 6619 .L310: + 6620 .LSM561: + 6621 0570 ED85 ldd r30,Y+13 + 6622 0572 FE85 ldd r31,Y+14 + 6623 .LVL626: + 6624 0574 22A5 ldd r18,Z+42 + 6625 0576 33A5 ldd r19,Z+43 + 6626 0578 44A5 ldd r20,Z+44 + 6627 057a 55A5 ldd r21,Z+45 + 6628 .LVL627: + 6629 057c ACA5 ldd r26,Y+44 + 6630 057e BDA5 ldd r27,Y+45 + 6631 .LVL628: + 6632 0580 5A96 adiw r26,26 + 6633 0582 2D93 st X+,r18 + 6634 0584 3D93 st X+,r19 + 6635 0586 4D93 st X+,r20 + 6636 0588 5C93 st X,r21 + 6637 058a 5D97 sbiw r26,26+3 + 6638 .LSM562: + 6639 058c 8F8D ldd r24,Y+31 + 6640 058e 98A1 ldd r25,Y+32 + 6641 .LVL629: + 6642 0590 5F96 adiw r26,30+1 + 6643 0592 9C93 st X,r25 + 6644 0594 8E93 st -X,r24 + 6645 0596 5E97 sbiw r26,30 + 6646 .LSM563: + 6647 0598 2DA1 ldd r18,Y+37 + 6648 059a 1496 adiw r26,4 + 6649 059c 2C93 st X,r18 + 6650 .LSM564: + 6651 059e D701 movw r26,r14 + 6652 05a0 5596 adiw r26,21 + 6653 05a2 3C91 ld r19,X + 6654 05a4 5597 sbiw r26,21 + 6655 .LVL630: + 6656 05a6 20E0 ldi r18,lo8(0) + 6657 05a8 5496 adiw r26,20 + 6658 05aa 8C91 ld r24,X + 6659 05ac 5497 sbiw r26,20 + 6660 05ae 90E0 ldi r25,lo8(0) + 6661 05b0 282B or r18,r24 + 6662 05b2 392B or r19,r25 + 6663 05b4 40E0 ldi r20,lo8(0) + 6664 05b6 50E0 ldi r21,hi8(0) + 6665 05b8 A901 movw r20,r18 + 6666 05ba 3327 clr r19 + 6667 05bc 2227 clr r18 + 6668 05be 5B96 adiw r26,27 + 6669 05c0 9C91 ld r25,X + 6670 05c2 5B97 sbiw r26,27 + 6671 05c4 80E0 ldi r24,lo8(0) + 6672 05c6 5A96 adiw r26,26 + 6673 05c8 6C91 ld r22,X + 6674 .LVL631: + 6675 05ca 70E0 ldi r23,lo8(0) + 6676 05cc 862B or r24,r22 + 6677 05ce 972B or r25,r23 + 6678 05d0 A0E0 ldi r26,lo8(0) + 6679 05d2 B0E0 ldi r27,hi8(0) + 6680 05d4 282B or r18,r24 + 6681 05d6 392B or r19,r25 + 6682 05d8 4A2B or r20,r26 + 6683 05da 5B2B or r21,r27 + 6684 05dc ACA5 ldd r26,Y+44 + 6685 05de BDA5 ldd r27,Y+45 + 6686 05e0 1E96 adiw r26,14 + 6687 05e2 2D93 st X+,r18 + 6688 05e4 3D93 st X+,r19 + 6689 05e6 4D93 st X+,r20 + 6690 05e8 5C93 st X,r21 + 6691 05ea 5197 sbiw r26,14+3 + 6692 .LSM565: + 6693 05ec D701 movw r26,r14 + 6694 05ee 5F96 adiw r26,31 + 6695 05f0 2C91 ld r18,X + 6696 05f2 5F97 sbiw r26,31 + 6697 05f4 30E0 ldi r19,lo8(0) + 6698 05f6 40E0 ldi r20,lo8(0) + 6699 05f8 50E0 ldi r21,hi8(0) + 6700 05fa 522F mov r21,r18 + 6701 05fc 4427 clr r20 + 6702 05fe 3327 clr r19 + 6703 0600 2227 clr r18 + 6704 .LVL632: + 6705 0602 5E96 adiw r26,30 + 6706 0604 8C91 ld r24,X + 6707 0606 90E0 ldi r25,lo8(0) + 6708 0608 A0E0 ldi r26,lo8(0) + 6709 060a B0E0 ldi r27,hi8(0) + 6710 060c DC01 movw r26,r24 + 6711 060e 9927 clr r25 + 6712 0610 8827 clr r24 + 6713 0612 282B or r18,r24 + 6714 0614 392B or r19,r25 + 6715 0616 4A2B or r20,r26 + 6716 0618 5B2B or r21,r27 + 6717 061a D701 movw r26,r14 + 6718 061c 5C96 adiw r26,28 + 6719 061e 8C91 ld r24,X + 6720 0620 90E0 ldi r25,lo8(0) + 6721 0622 A0E0 ldi r26,lo8(0) + 6722 0624 B0E0 ldi r27,hi8(0) + 6723 0626 282B or r18,r24 + 6724 0628 392B or r19,r25 + 6725 062a 4A2B or r20,r26 + 6726 062c 5B2B or r21,r27 + 6727 062e D701 movw r26,r14 + 6728 0630 5D96 adiw r26,29 + 6729 0632 9C91 ld r25,X + 6730 0634 80E0 ldi r24,lo8(0) + 6731 0636 A0E0 ldi r26,lo8(0) + 6732 0638 B0E0 ldi r27,hi8(0) + 6733 063a 282B or r18,r24 + 6734 063c 392B or r19,r25 + 6735 063e 4A2B or r20,r26 + 6736 0640 5B2B or r21,r27 + 6737 0642 ACA5 ldd r26,Y+44 + 6738 0644 BDA5 ldd r27,Y+45 + 6739 0646 1A96 adiw r26,10 + 6740 0648 2D93 st X+,r18 + 6741 064a 3D93 st X+,r19 + 6742 064c 4D93 st X+,r20 + 6743 064e 5C93 st X,r21 + 6744 0650 1D97 sbiw r26,10+3 + 6745 .LSM566: + 6746 0652 1696 adiw r26,6 + 6747 0654 1D92 st X+,__zero_reg__ + 6748 0656 1D92 st X+,__zero_reg__ + 6749 0658 1D92 st X+,__zero_reg__ + 6750 065a 1C92 st X,__zero_reg__ + 6751 065c 1997 sbiw r26,6+3 + 6752 065e 8FEF ldi r24,lo8(-1) + 6753 0660 1596 adiw r26,5 + 6754 0662 8C93 st X,r24 + 6755 .LSM567: + 6756 0664 ACA5 ldd r26,Y+44 + 6757 0666 BDA5 ldd r27,Y+45 + 6758 0668 5696 adiw r26,22 + 6759 066a 1D92 st X+,__zero_reg__ + 6760 066c 1D92 st X+,__zero_reg__ + 6761 066e 1D92 st X+,__zero_reg__ + 6762 0670 1C92 st X,__zero_reg__ + 6763 0672 5997 sbiw r26,22+3 + 6764 .LSM568: + 6765 0674 1196 adiw r26,1 + 6766 0676 FC93 st X,r31 + 6767 0678 EE93 st -X,r30 + 6768 067a 8681 ldd r24,Z+6 + 6769 067c 9781 ldd r25,Z+7 + 6770 067e 1396 adiw r26,2+1 + 6771 0680 9C93 st X,r25 + 6772 0682 8E93 st -X,r24 + 6773 0684 1297 sbiw r26,2 + 6774 0686 20E0 ldi r18,lo8(0) + 6775 .LVL633: + 6776 0688 00C0 rjmp .L262 + 6777 .LVL634: + 6778 .L302: + 6779 .LSM569: + 6780 068a 27E0 ldi r18,lo8(7) + 6781 068c 00C0 rjmp .L262 + 6782 .L311: + 6783 068e 24E0 ldi r18,lo8(4) + 6784 .LVL635: + 6785 .L262: + 6786 .LSM570: + 6787 0690 822F mov r24,r18 + 6788 /* epilogue start */ + 6789 0692 AD96 adiw r28,45 + 6790 0694 0FB6 in __tmp_reg__,__SREG__ + 6791 0696 F894 cli + 6792 0698 DEBF out __SP_H__,r29 + 6793 069a 0FBE out __SREG__,__tmp_reg__ + 6794 069c CDBF out __SP_L__,r28 + 6795 069e CF91 pop r28 + 6796 06a0 DF91 pop r29 + 6797 06a2 1F91 pop r17 + 6798 06a4 0F91 pop r16 + 6799 .LVL636: + 6800 06a6 FF90 pop r15 + 6801 06a8 EF90 pop r14 + 6802 .LVL637: + 6803 06aa DF90 pop r13 + 6804 06ac CF90 pop r12 + 6805 .LVL638: + 6806 06ae BF90 pop r11 + 6807 06b0 AF90 pop r10 + 6808 .LVL639: + 6809 06b2 9F90 pop r9 + 6810 06b4 8F90 pop r8 + 6811 06b6 7F90 pop r7 + 6812 06b8 6F90 pop r6 + 6813 06ba 5F90 pop r5 + 6814 06bc 4F90 pop r4 + 6815 06be 3F90 pop r3 + 6816 06c0 2F90 pop r2 + 6817 .LVL640: + 6818 06c2 0895 ret + 6819 .LVL641: + 6820 .L298: + 6821 .LBB51: + 6822 .LBB50: + 6823 .LSM571: + 6824 06c4 4B8D ldd r20,Y+27 + 6825 06c6 5C8D ldd r21,Y+28 + 6826 06c8 6D8D ldd r22,Y+29 + 6827 06ca 7E8D ldd r23,Y+30 + 6828 06cc 8D85 ldd r24,Y+13 + 6829 06ce 9E85 ldd r25,Y+14 + 6830 .LVL642: + 6831 06d0 0E94 0000 call move_window + 6832 .LVL643: + 6833 06d4 282F mov r18,r24 + 6834 .LVL644: + 6835 .LBB49: + 6836 .LSM572: + 6837 06d6 8823 tst r24 + 6838 06d8 01F4 brne .L262 + 6839 .LVL645: + 6840 06da 00C0 rjmp .L323 + 6841 .LVL646: + 6842 .L306: + 6843 .LBE49: + 6844 .LBE50: + 6845 .LSM573: + 6846 06dc ED85 ldd r30,Y+13 + 6847 06de FE85 ldd r31,Y+14 + 6848 06e0 0894 sec + 6849 06e2 2108 sbc r2,__zero_reg__ + 6850 06e4 3108 sbc r3,__zero_reg__ + 6851 06e6 4108 sbc r4,__zero_reg__ + 6852 06e8 5108 sbc r5,__zero_reg__ + 6853 .LVL647: + 6854 06ea 2286 std Z+10,r2 + 6855 06ec 3386 std Z+11,r3 + 6856 06ee 4486 std Z+12,r4 + 6857 06f0 5586 std Z+13,r5 + 6858 06f2 00C0 rjmp .L303 + 6859 .LVL648: + 6860 .L270: + 6861 06f4 9A2F mov r25,r26 + 6862 06f6 60E0 ldi r22,lo8(0) + 6863 .LVL649: + 6864 06f8 00C0 rjmp .L313 + 6865 .LBE51: + 6866 .LFE73: + 6868 .lcomm FatFs,2 + 6869 .lcomm Fsid,2 + 7070 .Letext0: +DEFINED SYMBOLS + *ABS*:00000000 ff.c +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:2 *ABS*:0000003f __SREG__ +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:3 *ABS*:0000003e __SP_H__ +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:4 *ABS*:0000003d __SP_L__ +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:5 *ABS*:00000034 __CCP__ +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:6 *ABS*:00000000 __tmp_reg__ +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:7 *ABS*:00000001 __zero_reg__ +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:18 .text.mem_cpy:00000000 mem_cpy +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:62 .text.mem_set:00000000 mem_set +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:93 .text.clust2sect:00000000 clust2sect +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:175 .text.f_mount:00000000 f_mount + .bss:00000000 FatFs +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:218 .text.validate:00000000 validate +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:257 .text.move_window:00000000 move_window +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:420 .text.put_fat:00000000 put_fat +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:740 .text.get_fat:00000000 get_fat +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:1027 .text.create_chain:00000000 create_chain +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:1350 .text.f_lseek:00000000 f_lseek +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:1924 .text.dir_seek:00000000 dir_seek +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:2173 .text.f_write:00000000 f_write +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:2744 .text.f_putc:00000000 f_putc +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:2807 .text.f_puts:00000000 f_puts +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:2868 .text.f_printf:00000000 f_printf +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:3356 .text.dir_next:00000000 dir_next +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:3698 .text.f_read:00000000 f_read +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:4143 .text.f_gets:00000000 f_gets +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:4257 .text.check_fs:00000000 check_fs +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:4412 .text.f_sync:00000000 f_sync +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:4723 .text.f_close:00000000 f_close +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:4754 .text.chk_mounted:00000000 chk_mounted +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:6868 .bss:00000002 Fsid +C:\Users\Dean\AppData\Local\Temp/ccGlxtj5.s:5604 .text.f_open:00000000 f_open + +UNDEFINED SYMBOLS +__mulsi3 +disk_status +disk_write +disk_read +__udivmodsi4 +get_fattime +disk_ioctl +disk_initialize +__do_copy_data +__do_clear_bss diff --git a/Projects/TemperatureDataLogger/Lib/FATFs/ffconf.h b/Projects/TemperatureDataLogger/Lib/FATFs/ffconf.h new file mode 100644 index 000000000..06859a046 --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/FATFs/ffconf.h @@ -0,0 +1,166 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module configuration file R0.07e (C)ChaN, 2009 +/----------------------------------------------------------------------------/ +/ +/ CAUTION! Do not forget to make clean the project after any changes to +/ the configuration options. +/ +/----------------------------------------------------------------------------*/ +#ifndef _FFCONFIG +#define _FFCONFIG 0x007E + + +/*---------------------------------------------------------------------------/ +/ Function and Buffer Configurations +/----------------------------------------------------------------------------*/ + +#define _FS_TINY 1 /* 0 or 1 */ +/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system +/ object instead of the sector buffer in the individual file object for file +/ data transfer. This reduces memory consumption 512 bytes each file object. */ + + +#define _FS_READONLY 0 /* 0 or 1 */ +/* Setting _FS_READONLY to 1 defines read only configuration. This removes +/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, +/ f_truncate and useless f_getfree. */ + + +#define _FS_MINIMIZE 2 /* 0, 1, 2 or 3 */ +/* The _FS_MINIMIZE option defines minimization level to remove some functions. +/ +/ 0: Full function. +/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename +/ are removed. +/ 2: f_opendir and f_readdir are removed in addition to level 1. +/ 3: f_lseek is removed in addition to level 2. */ + + +#define _USE_STRFUNC 1 /* 0, 1 or 2 */ +/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ + + +#define _USE_MKFS 0 /* 0 or 1 */ +/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ + + +#define _USE_FORWARD 0 /* 0 or 1 */ +/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ + + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/----------------------------------------------------------------------------*/ + +#define _CODE_PAGE 932 +/* The _CODE_PAGE specifies the OEM code page to be used on the target system. +/ Incorrect setting of the code page can cause a file open failure. +/ +/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows) +/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) +/ 949 - Korean (DBCS, OEM, Windows) +/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) +/ 1250 - Central Europe (Windows) +/ 1251 - Cyrillic (Windows) +/ 1252 - Latin 1 (Windows) +/ 1253 - Greek (Windows) +/ 1254 - Turkish (Windows) +/ 1255 - Hebrew (Windows) +/ 1256 - Arabic (Windows) +/ 1257 - Baltic (Windows) +/ 1258 - Vietnam (OEM, Windows) +/ 437 - U.S. (OEM) +/ 720 - Arabic (OEM) +/ 737 - Greek (OEM) +/ 775 - Baltic (OEM) +/ 850 - Multilingual Latin 1 (OEM) +/ 858 - Multilingual Latin 1 + Euro (OEM) +/ 852 - Latin 2 (OEM) +/ 855 - Cyrillic (OEM) +/ 866 - Russian (OEM) +/ 857 - Turkish (OEM) +/ 862 - Hebrew (OEM) +/ 874 - Thai (OEM, Windows) +/ 1 - ASCII only (Valid for non LFN cfg.) +*/ + + +#define _USE_LFN 0 /* 0, 1 or 2 */ +#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ +/* The _USE_LFN option switches the LFN support. +/ +/ 0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect. +/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ +/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN, +/ two Unicode handling functions ff_convert() and ff_wtoupper() must be added +/ to the project. */ + + +#define _LFN_UNICODE 0 /* 0 or 1 */ +/* To switch the character code set on FatFs API to Unicode, +/ enable LFN feature and set _LFN_UNICODE to 1. +*/ + + +#define _FS_RPATH 0 /* 0 or 1 */ +/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir, +/ f_chdrive function are available. +/ Note that output of the f_readdir fnction is affected by this option. */ + + + +/*---------------------------------------------------------------------------/ +/ Physical Drive Configurations +/----------------------------------------------------------------------------*/ + +#define _DRIVES 1 +/* Number of volumes (logical drives) to be used. */ + + +#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ +/* Maximum sector size to be handled. +/ Always set 512 for memory card and hard disk but a larger value may be +/ required for floppy disk (512/1024) and optical disk (512/2048). +/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted +/ to the disk_ioctl function. */ + + +#define _MULTI_PARTITION 0 /* 0 or 1 */ +/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical +/ drive number and can mount only first primaly partition. When it is set to 1, +/ each volume is tied to the partitions listed in Drives[]. */ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/----------------------------------------------------------------------------*/ + +#define _WORD_ACCESS 0 /* 0 or 1 */ +/* The _WORD_ACCESS option defines which access method is used to the word +/ data on the FAT volume. +/ +/ 0: Byte-by-byte access. Always compatible with all platforms. +/ 1: Word access. Do not choose this unless following condition is met. +/ +/ When the byte order on the memory is big-endian or address miss-aligned +/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0. +/ If it is not the case, the value can also be set to 1 to improve the +/ performance and code size. */ + + +#define _FS_REENTRANT 0 /* 0 or 1 */ +#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ +#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ +/* The _FS_REENTRANT option switches the reentrancy of the FatFs module. +/ +/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect. +/ 1: Enable reentrancy. Also user provided synchronization handlers, +/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj +/ function must be added to the project. */ + + +#endif /* _FFCONFIG */ diff --git a/Projects/TemperatureDataLogger/Lib/FATFs/integer.h b/Projects/TemperatureDataLogger/Lib/FATFs/integer.h new file mode 100644 index 000000000..1d6bac368 --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/FATFs/integer.h @@ -0,0 +1,37 @@ +/*-------------------------------------------*/ +/* Integer type definitions for FatFs module */ +/*-------------------------------------------*/ + +#ifndef _INTEGER + +#if 0 +#include +#else + +/* These types must be 16-bit, 32-bit or larger integer */ +typedef int INT; +typedef unsigned int UINT; + +/* These types must be 8-bit integer */ +typedef signed char CHAR; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; + +/* These types must be 16-bit integer */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* These types must be 32-bit integer */ +typedef long LONG; +typedef unsigned long ULONG; +typedef unsigned long DWORD; + +/* Boolean type */ +typedef enum { FALSE = 0, TRUE } BOOL; + +#endif + +#define _INTEGER +#endif diff --git a/Projects/TemperatureDataLogger/Lib/SCSI.c b/Projects/TemperatureDataLogger/Lib/SCSI.c new file mode 100644 index 000000000..d3272b0d7 --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/SCSI.c @@ -0,0 +1,281 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2009. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * SCSI command processing routines, for SCSI commands issued by the host. Mass Storage + * devices use a thin "Bulk-Only Transport" protocol for issuing commands and status information, + * which wrap around standard SCSI device commands for controlling the actual storage medium. + */ + +#define INCLUDE_FROM_SCSI_C +#include "SCSI.h" + +/** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's + * features and capabilities. + */ +SCSI_Inquiry_Response_t InquiryData = + { + .DeviceType = DEVICE_TYPE_BLOCK, + .PeripheralQualifier = 0, + + .Removable = true, + + .Version = 0, + + .ResponseDataFormat = 2, + .NormACA = false, + .TrmTsk = false, + .AERC = false, + + .AdditionalLength = 0x1F, + + .SoftReset = false, + .CmdQue = false, + .Linked = false, + .Sync = false, + .WideBus16Bit = false, + .WideBus32Bit = false, + .RelAddr = false, + + .VendorID = "LUFA", + .ProductID = "Dataflash Disk", + .RevisionID = {'0','.','0','0'}, + }; + +/** Structure to hold the sense data for the last issued SCSI command, which is returned to the host after a SCSI REQUEST SENSE + * command is issued. This gives information on exactly why the last command failed to complete. + */ +SCSI_Request_Sense_Response_t SenseData = + { + .ResponseCode = 0x70, + .AdditionalLength = 0x0A, + }; + + +/** Main routine to process the SCSI command located in the Command Block Wrapper read from the host. This dispatches + * to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns + * a command failure due to a ILLEGAL REQUEST. + * + * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with + */ +bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) +{ + /* Set initial sense data, before the requested command is processed */ + SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD, + SCSI_ASENSE_NO_ADDITIONAL_INFORMATION, + SCSI_ASENSEQ_NO_QUALIFIER); + + /* Run the appropriate SCSI command hander function based on the passed command */ + switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0]) + { + case SCSI_CMD_INQUIRY: + SCSI_Command_Inquiry(MSInterfaceInfo); + break; + case SCSI_CMD_REQUEST_SENSE: + SCSI_Command_Request_Sense(MSInterfaceInfo); + break; + case SCSI_CMD_READ_CAPACITY_10: + SCSI_Command_Read_Capacity_10(MSInterfaceInfo); + break; + case SCSI_CMD_SEND_DIAGNOSTIC: + SCSI_Command_Send_Diagnostic(MSInterfaceInfo); + break; + case SCSI_CMD_WRITE_10: + SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE); + break; + case SCSI_CMD_READ_10: + SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ); + break; + case SCSI_CMD_TEST_UNIT_READY: + case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + case SCSI_CMD_VERIFY_10: + /* These commands should just succeed, no handling required */ + MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0; + break; + default: + /* Update the SENSE key to reflect the invalid command */ + SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, + SCSI_ASENSE_INVALID_COMMAND, + SCSI_ASENSEQ_NO_QUALIFIER); + break; + } + + return (SenseData.SenseKey == SCSI_SENSE_KEY_GOOD); +} + +/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features + * and capabilities to the host. + * + * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with + */ +static void SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) +{ + uint16_t AllocationLength = (((uint16_t)MSInterfaceInfo->State.CommandBlock.SCSICommandData[3] << 8) | + MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]); + uint16_t BytesTransferred = (AllocationLength < sizeof(InquiryData))? AllocationLength : + sizeof(InquiryData); + + /* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */ + if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) || + MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]) + { + /* Optional but unsupported bits set - update the SENSE key and fail the request */ + SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, + SCSI_ASENSE_INVALID_FIELD_IN_CDB, + SCSI_ASENSEQ_NO_QUALIFIER); + + return; + } + + Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NO_STREAM_CALLBACK); + + uint8_t PadBytes[AllocationLength - BytesTransferred]; + + /* Pad out remaining bytes with 0x00 */ + Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); + + /* Finalize the stream transfer to send the last packet */ + Endpoint_ClearIN(); + + /* Succeed the command and update the bytes transferred counter */ + MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred; +} + +/** Command processing for an issued SCSI REQUEST SENSE command. This command returns information about the last issued command, + * including the error code and additional error information so that the host can determine why a command failed to complete. + * + * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with + */ +static void SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) +{ + uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]; + uint8_t BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData); + + uint8_t PadBytes[AllocationLength - BytesTransferred]; + + Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK); + Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); + Endpoint_ClearIN(); + + /* Succeed the command and update the bytes transferred counter */ + MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred; +} + +/** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity + * on the selected Logical Unit (drive), as a number of OS-sized blocks. + * + * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with + */ +static void SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) +{ + uint32_t LastBlockAddressInLUN = (VIRTUAL_MEMORY_BLOCKS - 1); + uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE; + + Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NO_STREAM_CALLBACK); + Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NO_STREAM_CALLBACK); + Endpoint_ClearIN(); + + /* Succeed the command and update the bytes transferred counter */ + MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8; +} + +/** Command processing for an issued SCSI SEND DIAGNOSTIC command. This command performs a quick check of the Dataflash ICs on the + * board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is + * supported. + * + * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with + */ +static void SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) +{ + /* Check to see if the SELF TEST bit is not set */ + if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2))) + { + /* Only self-test supported - update SENSE key and fail the command */ + SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, + SCSI_ASENSE_INVALID_FIELD_IN_CDB, + SCSI_ASENSEQ_NO_QUALIFIER); + + return; + } + + /* Check to see if all attached Dataflash ICs are functional */ + if (!(DataflashManager_CheckDataflashOperation())) + { + /* Update SENSE key with a hardware error condition and return command fail */ + SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR, + SCSI_ASENSE_NO_ADDITIONAL_INFORMATION, + SCSI_ASENSEQ_NO_QUALIFIER); + + return; + } + + /* Succeed the command and update the bytes transferred counter */ + MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0; +} + +/** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address + * and total number of blocks to process, then calls the appropriate low-level dataflash routine to handle the actual + * reading and writing of the data. + * + * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with + * \param[in] IsDataRead Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE) + */ +static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead) +{ + uint32_t BlockAddress; + uint16_t TotalBlocks; + + /* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */ + BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]); + + /* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */ + TotalBlocks = SwapEndian_16(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]); + + /* Check if the block address is outside the maximum allowable value for the LUN */ + if (BlockAddress >= VIRTUAL_MEMORY_BLOCKS) + { + /* Block address is invalid, update SENSE key and return command fail */ + SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, + SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, + SCSI_ASENSEQ_NO_QUALIFIER); + + return; + } + + /* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */ + if (IsDataRead == DATA_READ) + DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks); + else + DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks); + + /* Update the bytes transferred counter and succeed the command */ + MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE); +} diff --git a/Projects/TemperatureDataLogger/Lib/SCSI.h b/Projects/TemperatureDataLogger/Lib/SCSI.h new file mode 100644 index 000000000..d5d1d06f8 --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/SCSI.h @@ -0,0 +1,86 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2009. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Header file for SCSI.c. + */ + +#ifndef _SCSI_H_ +#define _SCSI_H_ + + /* Includes: */ + #include + #include + + #include + #include + + #include "../TempDataLogger.h" + #include "../Descriptors.h" + #include "DataflashManager.h" + + /* Macros: */ + /** Macro to set the current SCSI sense data to the given key, additional sense code and additional sense qualifier. This + * is for convenience, as it allows for all three sense values (returned upon request to the host to give information about + * the last command failure) in a quick and easy manner. + * + * \param[in] key New SCSI sense key to set the sense code to + * \param[in] acode New SCSI additional sense key to set the additional sense code to + * \param[in] aqual New SCSI additional sense key qualifier to set the additional sense qualifier code to + */ + #define SCSI_SET_SENSE(key, acode, aqual) MACROS{ SenseData.SenseKey = (key); \ + SenseData.AdditionalSenseCode = (acode); \ + SenseData.AdditionalSenseQualifier = (aqual); }MACROE + + /** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */ + #define DATA_READ true + + /** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */ + #define DATA_WRITE false + + /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */ + #define DEVICE_TYPE_BLOCK 0x00 + + /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */ + #define DEVICE_TYPE_CDROM 0x05 + + /* Function Prototypes: */ + bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); + + #if defined(INCLUDE_FROM_SCSI_C) + static void SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); + static void SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); + static void SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); + static void SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); + static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead); + #endif + +#endif diff --git a/Projects/TemperatureDataLogger/Lib/SCSI.lst b/Projects/TemperatureDataLogger/Lib/SCSI.lst new file mode 100644 index 000000000..c158b8549 --- /dev/null +++ b/Projects/TemperatureDataLogger/Lib/SCSI.lst @@ -0,0 +1,734 @@ + 1 .file "SCSI.c" + 2 __SREG__ = 0x3f + 3 __SP_H__ = 0x3e + 4 __SP_L__ = 0x3d + 5 __CCP__ = 0x34 + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 15 .Ltext0: + 16 .section .text.SCSI_Command_Inquiry,"ax",@progbits + 18 SCSI_Command_Inquiry: + 19 .LFB53: + 20 .LSM0: + 21 .LVL0: + 22 0000 8F92 push r8 + 23 0002 9F92 push r9 + 24 0004 AF92 push r10 + 25 0006 BF92 push r11 + 26 0008 CF92 push r12 + 27 000a DF92 push r13 + 28 000c EF92 push r14 + 29 000e FF92 push r15 + 30 0010 0F93 push r16 + 31 0012 1F93 push r17 + 32 0014 DF93 push r29 + 33 0016 CF93 push r28 + 34 0018 CDB7 in r28,__SP_L__ + 35 001a DEB7 in r29,__SP_H__ + 36 /* prologue: function */ + 37 /* frame size = 0 */ + 38 001c 6C01 movw r12,r24 + 39 .LSM1: + 40 001e ADB6 in r10,__SP_L__ + 41 0020 BEB6 in r11,__SP_H__ + 42 .LSM2: + 43 0022 9DB6 in r9,__SP_L__ + 44 0024 8EB6 in r8,__SP_H__ + 45 .LSM3: + 46 0026 FC01 movw r30,r24 + 47 0028 248D ldd r18,Z+28 + 48 002a 658D ldd r22,Z+29 + 49 .LSM4: + 50 002c 828D ldd r24,Z+26 + 51 .LVL1: + 52 002e 90E0 ldi r25,lo8(0) + 53 0030 8370 andi r24,lo8(3) + 54 0032 9070 andi r25,hi8(3) + 55 0034 892B or r24,r25 + 56 0036 01F4 brne .L2 + 57 0038 838D ldd r24,Z+27 + 58 003a 8823 tst r24 + 59 003c 01F0 breq .L3 + 60 .L2: + 61 .LSM5: + 62 003e 8091 0000 lds r24,SenseData+2 + 63 0042 807F andi r24,lo8(-16) + 64 0044 8560 ori r24,lo8(5) + 65 0046 8093 0000 sts SenseData+2,r24 + 66 004a 84E2 ldi r24,lo8(36) + 67 004c 8093 0000 sts SenseData+12,r24 + 68 0050 1092 0000 sts SenseData+13,__zero_reg__ + 69 0054 00C0 rjmp .L7 + 70 .L3: + 71 .LSM6: + 72 0056 922F mov r25,r18 + 73 0058 80E0 ldi r24,lo8(0) + 74 005a 062F mov r16,r22 + 75 .LVL2: + 76 005c 10E0 ldi r17,lo8(0) + 77 .LVL3: + 78 005e 082B or r16,r24 + 79 0060 192B or r17,r25 + 80 .LVL4: + 81 .LSM7: + 82 0062 7801 movw r14,r16 + 83 .LVL5: + 84 0064 0532 cpi r16,37 + 85 0066 1105 cpc r17,__zero_reg__ + 86 0068 00F0 brlo .L5 + 87 006a 84E2 ldi r24,lo8(36) + 88 006c E82E mov r14,r24 + 89 006e F12C mov r15,__zero_reg__ + 90 .L5: + 91 .LSM8: + 92 0070 80E0 ldi r24,lo8(InquiryData) + 93 0072 90E0 ldi r25,hi8(InquiryData) + 94 0074 B701 movw r22,r14 + 95 0076 40E0 ldi r20,lo8(0) + 96 0078 50E0 ldi r21,hi8(0) + 97 007a 0E94 0000 call Endpoint_Write_Stream_LE + 98 .LSM9: + 99 007e B801 movw r22,r16 + 100 0080 6E19 sub r22,r14 + 101 0082 7F09 sbc r23,r15 + 102 0084 8DB7 in r24,__SP_L__ + 103 0086 9EB7 in r25,__SP_H__ + 104 0088 861B sub r24,r22 + 105 008a 970B sbc r25,r23 + 106 008c 0FB6 in __tmp_reg__,__SREG__ + 107 008e F894 cli + 108 0090 9EBF out __SP_H__,r25 + 109 0092 0FBE out __SREG__,__tmp_reg__ + 110 0094 8DBF out __SP_L__,r24 + 111 .LSM10: + 112 0096 0196 adiw r24,1 + 113 0098 40E0 ldi r20,lo8(0) + 114 009a 50E0 ldi r21,hi8(0) + 115 009c 0E94 0000 call Endpoint_Write_Stream_LE + 116 .LBB6: + 117 .LSM11: + 118 00a0 8091 E800 lds r24,232 + 119 .LVL6: + 120 00a4 982F mov r25,r24 + 121 00a6 9E7F andi r25,lo8(-2) + 122 00a8 9093 E800 sts 232,r25 + 123 00ac 8F77 andi r24,lo8(127) + 124 00ae 8093 E800 sts 232,r24 + 125 .LBE6: + 126 .LSM12: + 127 00b2 9701 movw r18,r14 + 128 00b4 40E0 ldi r20,lo8(0) + 129 00b6 50E0 ldi r21,hi8(0) + 130 .LVL7: + 131 00b8 F601 movw r30,r12 + 132 00ba 8289 ldd r24,Z+18 + 133 00bc 9389 ldd r25,Z+19 + 134 00be A489 ldd r26,Z+20 + 135 00c0 B589 ldd r27,Z+21 + 136 .LVL8: + 137 00c2 821B sub r24,r18 + 138 00c4 930B sbc r25,r19 + 139 00c6 A40B sbc r26,r20 + 140 00c8 B50B sbc r27,r21 + 141 00ca 828B std Z+18,r24 + 142 00cc 938B std Z+19,r25 + 143 00ce A48B std Z+20,r26 + 144 00d0 B58B std Z+21,r27 + 145 .LVL9: + 146 .L7: + 147 00d2 292D mov r18,r9 + 148 .LVL10: + 149 00d4 382D mov r19,r8 + 150 00d6 C901 movw r24,r18 + 151 00d8 0FB6 in __tmp_reg__,__SREG__ + 152 00da F894 cli + 153 00dc 9EBF out __SP_H__,r25 + 154 00de 0FBE out __SREG__,__tmp_reg__ + 155 00e0 8DBF out __SP_L__,r24 + 156 .LSM13: + 157 00e2 0FB6 in __tmp_reg__,__SREG__ + 158 00e4 F894 cli + 159 00e6 BEBE out __SP_H__,r11 + 160 00e8 0FBE out __SREG__,__tmp_reg__ + 161 00ea ADBE out __SP_L__,r10 + 162 /* epilogue start */ + 163 00ec CF91 pop r28 + 164 00ee DF91 pop r29 + 165 00f0 1F91 pop r17 + 166 .LVL11: + 167 00f2 0F91 pop r16 + 168 .LVL12: + 169 00f4 FF90 pop r15 + 170 00f6 EF90 pop r14 + 171 .LVL13: + 172 00f8 DF90 pop r13 + 173 00fa CF90 pop r12 + 174 .LVL14: + 175 00fc BF90 pop r11 + 176 00fe AF90 pop r10 + 177 0100 9F90 pop r9 + 178 0102 8F90 pop r8 + 179 0104 0895 ret + 180 .LFE53: + 182 .section .text.SCSI_Command_Request_Sense,"ax",@progbits + 184 SCSI_Command_Request_Sense: + 185 .LFB54: + 186 .LSM14: + 187 .LVL15: + 188 0000 8F92 push r8 + 189 0002 9F92 push r9 + 190 0004 BF92 push r11 + 191 0006 CF92 push r12 + 192 0008 DF92 push r13 + 193 000a EF92 push r14 + 194 000c FF92 push r15 + 195 000e 0F93 push r16 + 196 0010 1F93 push r17 + 197 0012 DF93 push r29 + 198 0014 CF93 push r28 + 199 0016 CDB7 in r28,__SP_L__ + 200 0018 DEB7 in r29,__SP_H__ + 201 /* prologue: function */ + 202 /* frame size = 0 */ + 203 001a 6C01 movw r12,r24 + 204 .LSM15: + 205 001c 8DB6 in r8,__SP_L__ + 206 001e 9EB6 in r9,__SP_H__ + 207 .LSM16: + 208 0020 FC01 movw r30,r24 + 209 0022 058D ldd r16,Z+29 + 210 .LVL16: + 211 .LSM17: + 212 0024 B02E mov r11,r16 + 213 .LVL17: + 214 0026 0331 cpi r16,lo8(19) + 215 0028 00F0 brlo .L9 + 216 002a 92E1 ldi r25,lo8(18) + 217 002c B92E mov r11,r25 + 218 .L9: + 219 .LSM18: + 220 002e 10E0 ldi r17,lo8(0) + 221 0030 0B19 sub r16,r11 + 222 0032 1109 sbc r17,__zero_reg__ + 223 .LVL18: + 224 0034 8DB7 in r24,__SP_L__ + 225 0036 9EB7 in r25,__SP_H__ + 226 .LVL19: + 227 0038 801B sub r24,r16 + 228 003a 910B sbc r25,r17 + 229 003c 0FB6 in __tmp_reg__,__SREG__ + 230 003e F894 cli + 231 0040 9EBF out __SP_H__,r25 + 232 0042 0FBE out __SREG__,__tmp_reg__ + 233 0044 8DBF out __SP_L__,r24 + 234 0046 EDB6 in r14,__SP_L__ + 235 0048 FEB6 in r15,__SP_H__ + 236 004a 0894 sec + 237 004c E11C adc r14,__zero_reg__ + 238 004e F11C adc r15,__zero_reg__ + 239 .LSM19: + 240 0050 80E0 ldi r24,lo8(SenseData) + 241 0052 90E0 ldi r25,hi8(SenseData) + 242 0054 6B2D mov r22,r11 + 243 0056 70E0 ldi r23,lo8(0) + 244 0058 40E0 ldi r20,lo8(0) + 245 005a 50E0 ldi r21,hi8(0) + 246 005c 0E94 0000 call Endpoint_Write_Stream_LE + 247 .LSM20: + 248 0060 C701 movw r24,r14 + 249 0062 B801 movw r22,r16 + 250 0064 40E0 ldi r20,lo8(0) + 251 0066 50E0 ldi r21,hi8(0) + 252 0068 0E94 0000 call Endpoint_Write_Stream_LE + 253 .LBB7: + 254 .LSM21: + 255 006c 8091 E800 lds r24,232 + 256 .LVL20: + 257 0070 982F mov r25,r24 + 258 0072 9E7F andi r25,lo8(-2) + 259 0074 9093 E800 sts 232,r25 + 260 0078 8F77 andi r24,lo8(127) + 261 007a 8093 E800 sts 232,r24 + 262 .LBE7: + 263 .LSM22: + 264 007e F601 movw r30,r12 + 265 0080 8289 ldd r24,Z+18 + 266 0082 9389 ldd r25,Z+19 + 267 0084 A489 ldd r26,Z+20 + 268 0086 B589 ldd r27,Z+21 + 269 .LVL21: + 270 0088 8B19 sub r24,r11 + 271 008a 9109 sbc r25,__zero_reg__ + 272 008c A109 sbc r26,__zero_reg__ + 273 008e B109 sbc r27,__zero_reg__ + 274 0090 828B std Z+18,r24 + 275 0092 938B std Z+19,r25 + 276 0094 A48B std Z+20,r26 + 277 0096 B58B std Z+21,r27 + 278 .LSM23: + 279 0098 0FB6 in __tmp_reg__,__SREG__ + 280 009a F894 cli + 281 009c 9EBE out __SP_H__,r9 + 282 009e 0FBE out __SREG__,__tmp_reg__ + 283 00a0 8DBE out __SP_L__,r8 + 284 /* epilogue start */ + 285 00a2 CF91 pop r28 + 286 00a4 DF91 pop r29 + 287 00a6 1F91 pop r17 + 288 00a8 0F91 pop r16 + 289 00aa FF90 pop r15 + 290 00ac EF90 pop r14 + 291 00ae DF90 pop r13 + 292 00b0 CF90 pop r12 + 293 .LVL22: + 294 00b2 BF90 pop r11 + 295 .LVL23: + 296 00b4 9F90 pop r9 + 297 00b6 8F90 pop r8 + 298 00b8 0895 ret + 299 .LFE54: + 301 .section .text.SCSI_Command_ReadWrite_10,"ax",@progbits + 303 SCSI_Command_ReadWrite_10: + 304 .LFB57: + 305 .LSM24: + 306 .LVL24: + 307 0000 CF92 push r12 + 308 0002 DF92 push r13 + 309 0004 EF92 push r14 + 310 0006 FF92 push r15 + 311 0008 0F93 push r16 + 312 000a 1F93 push r17 + 313 000c CF93 push r28 + 314 000e DF93 push r29 + 315 /* prologue: function */ + 316 /* frame size = 0 */ + 317 0010 6C01 movw r12,r24 + 318 .LSM25: + 319 0012 FC01 movw r30,r24 + 320 0014 838D ldd r24,Z+27 + 321 0016 948D ldd r25,Z+28 + 322 0018 A58D ldd r26,Z+29 + 323 001a B68D ldd r27,Z+30 + 324 .LVL25: + 325 .LBB8: + 326 .LBB9: + 327 .LSM26: + 328 001c 182F mov r17,r24 + 329 001e 0027 clr r16 + 330 0020 FF24 clr r15 + 331 0022 EE24 clr r14 + 332 .LVL26: + 333 0024 2B2F mov r18,r27 + 334 0026 3327 clr r19 + 335 0028 4427 clr r20 + 336 002a 5527 clr r21 + 337 002c E22A or r14,r18 + 338 002e F32A or r15,r19 + 339 0030 042B or r16,r20 + 340 0032 152B or r17,r21 + 341 0034 9C01 movw r18,r24 + 342 0036 AD01 movw r20,r26 + 343 0038 2070 andi r18,lo8(16711680) + 344 003a 3070 andi r19,hi8(16711680) + 345 003c 5070 andi r21,hhi8(16711680) + 346 003e 232F mov r18,r19 + 347 0040 342F mov r19,r20 + 348 0042 452F mov r20,r21 + 349 0044 5527 clr r21 + 350 0046 E22A or r14,r18 + 351 0048 F32A or r15,r19 + 352 004a 042B or r16,r20 + 353 004c 152B or r17,r21 + 354 004e 8070 andi r24,lo8(65280) + 355 0050 A070 andi r26,hlo8(65280) + 356 0052 B070 andi r27,hhi8(65280) + 357 0054 BA2F mov r27,r26 + 358 0056 A92F mov r26,r25 + 359 0058 982F mov r25,r24 + 360 005a 8827 clr r24 + 361 005c E82A or r14,r24 + 362 005e F92A or r15,r25 + 363 0060 0A2B or r16,r26 + 364 0062 1B2B or r17,r27 + 365 .LBE9: + 366 .LBE8: + 367 .LSM27: + 368 0064 80A1 ldd r24,Z+32 + 369 0066 91A1 ldd r25,Z+33 + 370 .LSM28: + 371 0068 F0E0 ldi r31,lo8(32768) + 372 006a EF16 cp r14,r31 + 373 006c F0E8 ldi r31,hi8(32768) + 374 006e FF06 cpc r15,r31 + 375 0070 F0E0 ldi r31,hlo8(32768) + 376 0072 0F07 cpc r16,r31 + 377 0074 F0E0 ldi r31,hhi8(32768) + 378 0076 1F07 cpc r17,r31 + 379 0078 00F0 brlo .L12 + 380 .LSM29: + 381 007a 8091 0000 lds r24,SenseData+2 + 382 007e 807F andi r24,lo8(-16) + 383 0080 8560 ori r24,lo8(5) + 384 0082 8093 0000 sts SenseData+2,r24 + 385 0086 81E2 ldi r24,lo8(33) + 386 0088 8093 0000 sts SenseData+12,r24 + 387 008c 1092 0000 sts SenseData+13,__zero_reg__ + 388 0090 00C0 rjmp .L16 + 389 .L12: + 390 .LBB10: + 391 .LBB11: + 392 .LSM30: + 393 0092 D82F mov r29,r24 + 394 .LVL27: + 395 0094 C92F mov r28,r25 + 396 .LVL28: + 397 .LBE11: + 398 .LBE10: + 399 .LSM31: + 400 0096 6623 tst r22 + 401 0098 01F0 breq .L14 + 402 .LSM32: + 403 009a C601 movw r24,r12 + 404 009c B801 movw r22,r16 + 405 009e A701 movw r20,r14 + 406 00a0 9E01 movw r18,r28 + 407 00a2 0E94 0000 call DataflashManager_ReadBlocks + 408 .LVL29: + 409 00a6 00C0 rjmp .L15 + 410 .LVL30: + 411 .L14: + 412 .LSM33: + 413 00a8 C601 movw r24,r12 + 414 00aa B801 movw r22,r16 + 415 00ac A701 movw r20,r14 + 416 00ae 9E01 movw r18,r28 + 417 00b0 0E94 0000 call DataflashManager_WriteBlocks + 418 .LVL31: + 419 .L15: + 420 .LSM34: + 421 00b4 9E01 movw r18,r28 + 422 00b6 40E0 ldi r20,lo8(0) + 423 00b8 50E0 ldi r21,hi8(0) + 424 .LVL32: + 425 00ba 69E0 ldi r22,9 + 426 00bc 220F 1: lsl r18 + 427 00be 331F rol r19 + 428 00c0 441F rol r20 + 429 00c2 551F rol r21 + 430 00c4 6A95 dec r22 + 431 00c6 01F4 brne 1b + 432 .LVL33: + 433 00c8 F601 movw r30,r12 + 434 00ca 8289 ldd r24,Z+18 + 435 00cc 9389 ldd r25,Z+19 + 436 00ce A489 ldd r26,Z+20 + 437 00d0 B589 ldd r27,Z+21 + 438 00d2 821B sub r24,r18 + 439 00d4 930B sbc r25,r19 + 440 00d6 A40B sbc r26,r20 + 441 00d8 B50B sbc r27,r21 + 442 00da 828B std Z+18,r24 + 443 00dc 938B std Z+19,r25 + 444 00de A48B std Z+20,r26 + 445 00e0 B58B std Z+21,r27 + 446 .LVL34: + 447 .L16: + 448 /* epilogue start */ + 449 .LSM35: + 450 00e2 DF91 pop r29 + 451 .LVL35: + 452 00e4 CF91 pop r28 + 453 00e6 1F91 pop r17 + 454 00e8 0F91 pop r16 + 455 00ea FF90 pop r15 + 456 00ec EF90 pop r14 + 457 .LVL36: + 458 00ee DF90 pop r13 + 459 00f0 CF90 pop r12 + 460 .LVL37: + 461 00f2 0895 ret + 462 .LFE57: + 464 .section .text.SCSI_DecodeSCSICommand,"ax",@progbits + 465 .global SCSI_DecodeSCSICommand + 467 SCSI_DecodeSCSICommand: + 468 .LFB52: + 469 .LSM36: + 470 .LVL38: + 471 0000 0F93 push r16 + 472 0002 1F93 push r17 + 473 0004 DF93 push r29 + 474 0006 CF93 push r28 + 475 0008 CDB7 in r28,__SP_L__ + 476 000a DEB7 in r29,__SP_H__ + 477 000c 2897 sbiw r28,8 + 478 000e 0FB6 in __tmp_reg__,__SREG__ + 479 0010 F894 cli + 480 0012 DEBF out __SP_H__,r29 + 481 0014 0FBE out __SREG__,__tmp_reg__ + 482 0016 CDBF out __SP_L__,r28 + 483 /* prologue: function */ + 484 /* frame size = 8 */ + 485 0018 8C01 movw r16,r24 + 486 .LSM37: + 487 001a 9091 0000 lds r25,SenseData+2 + 488 001e 907F andi r25,lo8(-16) + 489 0020 9093 0000 sts SenseData+2,r25 + 490 0024 1092 0000 sts SenseData+12,__zero_reg__ + 491 0028 1092 0000 sts SenseData+13,__zero_reg__ + 492 .LSM38: + 493 002c F801 movw r30,r16 + 494 002e 818D ldd r24,Z+25 + 495 .LVL39: + 496 0030 8E31 cpi r24,lo8(30) + 497 0032 01F4 brne .+2 + 498 0034 00C0 rjmp .L19 + 499 0036 8F31 cpi r24,lo8(31) + 500 0038 00F4 brsh .L26 + 501 003a 8330 cpi r24,lo8(3) + 502 003c 01F0 breq .L20 + 503 003e 8430 cpi r24,lo8(4) + 504 0040 00F4 brsh .L27 + 505 0042 8823 tst r24 + 506 0044 01F4 brne .+2 + 507 0046 00C0 rjmp .L19 + 508 0048 00C0 rjmp .L18 + 509 .L27: + 510 004a 8231 cpi r24,lo8(18) + 511 004c 01F0 breq .L21 + 512 004e 8D31 cpi r24,lo8(29) + 513 0050 01F0 breq .+2 + 514 0052 00C0 rjmp .L18 + 515 0054 00C0 rjmp .L37 + 516 .L26: + 517 0056 8832 cpi r24,lo8(40) + 518 0058 01F4 brne .+2 + 519 005a 00C0 rjmp .L24 + 520 005c 8932 cpi r24,lo8(41) + 521 005e 00F4 brsh .L28 + 522 0060 8532 cpi r24,lo8(37) + 523 0062 01F0 breq .+2 + 524 0064 00C0 rjmp .L18 + 525 0066 00C0 rjmp .L38 + 526 .L28: + 527 0068 8A32 cpi r24,lo8(42) + 528 006a 01F4 brne .+2 + 529 006c 00C0 rjmp .L25 + 530 006e 8F32 cpi r24,lo8(47) + 531 0070 01F0 breq .+2 + 532 0072 00C0 rjmp .L18 + 533 0074 00C0 rjmp .L19 + 534 .L21: + 535 .LSM39: + 536 0076 C801 movw r24,r16 + 537 0078 0E94 0000 call SCSI_Command_Inquiry + 538 007c 00C0 rjmp .L29 + 539 .L20: + 540 .LSM40: + 541 007e C801 movw r24,r16 + 542 0080 0E94 0000 call SCSI_Command_Request_Sense + 543 0084 00C0 rjmp .L29 + 544 .L38: + 545 .LBB17: + 546 .LBB18: + 547 .LSM41: + 548 0086 8FEF ldi r24,lo8(32767) + 549 0088 9FE7 ldi r25,hi8(32767) + 550 008a A0E0 ldi r26,hlo8(32767) + 551 008c B0E0 ldi r27,hhi8(32767) + 552 008e 8983 std Y+1,r24 + 553 0090 9A83 std Y+2,r25 + 554 0092 AB83 std Y+3,r26 + 555 0094 BC83 std Y+4,r27 + 556 .LVL40: + 557 .LSM42: + 558 0096 80E0 ldi r24,lo8(512) + 559 0098 92E0 ldi r25,hi8(512) + 560 009a A0E0 ldi r26,hlo8(512) + 561 009c B0E0 ldi r27,hhi8(512) + 562 009e 8D83 std Y+5,r24 + 563 00a0 9E83 std Y+6,r25 + 564 00a2 AF83 std Y+7,r26 + 565 00a4 B887 std Y+8,r27 + 566 .LVL41: + 567 .LSM43: + 568 00a6 CE01 movw r24,r28 + 569 00a8 0196 adiw r24,1 + 570 00aa 64E0 ldi r22,lo8(4) + 571 00ac 70E0 ldi r23,hi8(4) + 572 00ae 40E0 ldi r20,lo8(0) + 573 00b0 50E0 ldi r21,hi8(0) + 574 00b2 0E94 0000 call Endpoint_Write_Stream_BE + 575 .LSM44: + 576 00b6 CE01 movw r24,r28 + 577 00b8 0596 adiw r24,5 + 578 00ba 64E0 ldi r22,lo8(4) + 579 00bc 70E0 ldi r23,hi8(4) + 580 00be 40E0 ldi r20,lo8(0) + 581 00c0 50E0 ldi r21,hi8(0) + 582 00c2 0E94 0000 call Endpoint_Write_Stream_BE + 583 .LBB19: + 584 .LSM45: + 585 00c6 8091 E800 lds r24,232 + 586 .LVL42: + 587 00ca 982F mov r25,r24 + 588 00cc 9E7F andi r25,lo8(-2) + 589 00ce 9093 E800 sts 232,r25 + 590 00d2 8F77 andi r24,lo8(127) + 591 00d4 8093 E800 sts 232,r24 + 592 .LBE19: + 593 .LSM46: + 594 00d8 F801 movw r30,r16 + 595 00da 8289 ldd r24,Z+18 + 596 00dc 9389 ldd r25,Z+19 + 597 00de A489 ldd r26,Z+20 + 598 00e0 B589 ldd r27,Z+21 + 599 .LVL43: + 600 00e2 0897 sbiw r24,8 + 601 00e4 A109 sbc r26,__zero_reg__ + 602 00e6 B109 sbc r27,__zero_reg__ + 603 00e8 828B std Z+18,r24 + 604 00ea 938B std Z+19,r25 + 605 00ec A48B std Z+20,r26 + 606 00ee B58B std Z+21,r27 + 607 00f0 00C0 rjmp .L29 + 608 .LVL44: + 609 .L37: + 610 .LBE18: + 611 .LBE17: + 612 .LBB20: + 613 .LBB21: + 614 .LSM47: + 615 00f2 F801 movw r30,r16 + 616 00f4 828D ldd r24,Z+26 + 617 00f6 82FD sbrc r24,2 + 618 00f8 00C0 rjmp .L30 + 619 .LSM48: + 620 00fa 9560 ori r25,lo8(5) + 621 00fc 9093 0000 sts SenseData+2,r25 + 622 0100 84E2 ldi r24,lo8(36) + 623 0102 00C0 rjmp .L36 + 624 .L30: + 625 .LBE21: + 626 .LSM49: + 627 0104 0E94 0000 call DataflashManager_CheckDataflashOperation + 628 .LBB22: + 629 0108 8823 tst r24 + 630 010a 01F4 brne .L19 + 631 .LSM50: + 632 010c 8091 0000 lds r24,SenseData+2 + 633 0110 807F andi r24,lo8(-16) + 634 0112 8460 ori r24,lo8(4) + 635 0114 8093 0000 sts SenseData+2,r24 + 636 0118 1092 0000 sts SenseData+12,__zero_reg__ + 637 011c 00C0 rjmp .L34 + 638 .L25: + 639 .LBE22: + 640 .LBE20: + 641 .LSM51: + 642 011e C801 movw r24,r16 + 643 0120 60E0 ldi r22,lo8(0) + 644 0122 00C0 rjmp .L35 + 645 .L24: + 646 .LSM52: + 647 0124 C801 movw r24,r16 + 648 0126 61E0 ldi r22,lo8(1) + 649 .L35: + 650 0128 0E94 0000 call SCSI_Command_ReadWrite_10 + 651 012c 00C0 rjmp .L29 + 652 .L19: + 653 .LSM53: + 654 012e F801 movw r30,r16 + 655 0130 128A std Z+18,__zero_reg__ + 656 0132 138A std Z+19,__zero_reg__ + 657 0134 148A std Z+20,__zero_reg__ + 658 0136 158A std Z+21,__zero_reg__ + 659 0138 00C0 rjmp .L29 + 660 .L18: + 661 .LSM54: + 662 013a 8091 0000 lds r24,SenseData+2 + 663 013e 807F andi r24,lo8(-16) + 664 0140 8560 ori r24,lo8(5) + 665 0142 8093 0000 sts SenseData+2,r24 + 666 0146 80E2 ldi r24,lo8(32) + 667 .L36: + 668 0148 8093 0000 sts SenseData+12,r24 + 669 .L34: + 670 014c 1092 0000 sts SenseData+13,__zero_reg__ + 671 .LVL45: + 672 .L29: + 673 0150 90E0 ldi r25,lo8(0) + 674 0152 8091 0000 lds r24,SenseData+2 + 675 0156 8F70 andi r24,lo8(15) + 676 0158 01F4 brne .L32 + 677 015a 91E0 ldi r25,lo8(1) + 678 .L32: + 679 .LSM55: + 680 015c 892F mov r24,r25 + 681 /* epilogue start */ + 682 015e 2896 adiw r28,8 + 683 0160 0FB6 in __tmp_reg__,__SREG__ + 684 0162 F894 cli + 685 0164 DEBF out __SP_H__,r29 + 686 0166 0FBE out __SREG__,__tmp_reg__ + 687 0168 CDBF out __SP_L__,r28 + 688 016a CF91 pop r28 + 689 016c DF91 pop r29 + 690 016e 1F91 pop r17 + 691 0170 0F91 pop r16 + 692 .LVL46: + 693 0172 0895 ret + 694 .LFE52: + 696 .global InquiryData + 697 .data + 700 InquiryData: + 701 0000 00 .byte 0 + 702 0001 80 .byte 128 + 703 0002 00 .byte 0 + 704 0003 02 .byte 2 + 705 0004 1F .byte 31 + 706 0005 0000 .skip 2,0 + 707 0007 00 .byte 0 + 708 0008 4C55 4641 .string "LUFA" + 708 00 + 709 000d 0000 00 .skip 3,0 + 710 0010 4461 7461 .string "Dataflash Disk" + 710 666C 6173 + 710 6820 4469 + 710 736B 00 + 711 001f 00 .skip 1,0 + 712 0020 30 .byte 48 + 713 0021 2E .byte 46 + 714 0022 30 .byte 48 + 715 0023 30 .byte 48 + 716 .global SenseData + 719 SenseData: + 720 0024 70 .byte 112 + 721 0025 0000 0000 .skip 6,0 + 721 0000 + 722 002b 0A .byte 10 + 723 002c 0000 0000 .skip 10,0 + 723 0000 0000 + 723 0000 + 772 .Letext0: +DEFINED SYMBOLS + *ABS*:00000000 SCSI.c +C:\Users\Dean\AppData\Local\Temp/ccIi4Dyn.s:2 *ABS*:0000003f __SREG__ +C:\Users\Dean\AppData\Local\Temp/ccIi4Dyn.s:3 *ABS*:0000003e __SP_H__ +C:\Users\Dean\AppData\Local\Temp/ccIi4Dyn.s:4 *ABS*:0000003d __SP_L__ +C:\Users\Dean\AppData\Local\Temp/ccIi4Dyn.s:5 *ABS*:00000034 __CCP__ +C:\Users\Dean\AppData\Local\Temp/ccIi4Dyn.s:6 *ABS*:00000000 __tmp_reg__ +C:\Users\Dean\AppData\Local\Temp/ccIi4Dyn.s:7 *ABS*:00000001 __zero_reg__ +C:\Users\Dean\AppData\Local\Temp/ccIi4Dyn.s:18 .text.SCSI_Command_Inquiry:00000000 SCSI_Command_Inquiry +C:\Users\Dean\AppData\Local\Temp/ccIi4Dyn.s:719 .data:00000024 SenseData +C:\Users\Dean\AppData\Local\Temp/ccIi4Dyn.s:700 .data:00000000 InquiryData +C:\Users\Dean\AppData\Local\Temp/ccIi4Dyn.s:184 .text.SCSI_Command_Request_Sense:00000000 SCSI_Command_Request_Sense +C:\Users\Dean\AppData\Local\Temp/ccIi4Dyn.s:303 .text.SCSI_Command_ReadWrite_10:00000000 SCSI_Command_ReadWrite_10 +C:\Users\Dean\AppData\Local\Temp/ccIi4Dyn.s:467 .text.SCSI_DecodeSCSICommand:00000000 SCSI_DecodeSCSICommand + +UNDEFINED SYMBOLS +Endpoint_Write_Stream_LE +DataflashManager_ReadBlocks +DataflashManager_WriteBlocks +Endpoint_Write_Stream_BE +DataflashManager_CheckDataflashOperation +__do_copy_data diff --git a/Projects/TemperatureDataLogger/TempDataLogger.c b/Projects/TemperatureDataLogger/TempDataLogger.c new file mode 100644 index 000000000..6cb1792a4 --- /dev/null +++ b/Projects/TemperatureDataLogger/TempDataLogger.c @@ -0,0 +1,187 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2009. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Main source file for the TemperatureDataLogger project. This file contains the main tasks of + * the project and is responsible for the initial application hardware configuration. + */ + +#include "TempDataLogger.h" + +/** LUFA Mass Storage Class driver interface configuration and state information. This structure is + * passed to all Mass Storage Class driver functions, so that multiple instances of the same class + * within a device can be differentiated from one another. + */ +USB_ClassInfo_MS_Device_t Disk_MS_Interface = + { + .Config = + { + .InterfaceNumber = 0, + + .DataINEndpointNumber = MASS_STORAGE_IN_EPNUM, + .DataINEndpointSize = MASS_STORAGE_IO_EPSIZE, + .DataINEndpointDoubleBank = false, + + .DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM, + .DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE, + .DataOUTEndpointDoubleBank = false, + + .TotalLUNs = 1, + }, + }; + +/** FAT Fs structure to hold the internal state of the FAT driver for the dataflash contents. */ +FATFS DiskFATState; + +/** FAT Fs structure to hold a FAT file handle for the log data write destination. */ +FIL TempLogFile; + +/** Counter to count the number of 10 millisecond tick that has elapsed since the last sample */ +uint16_t CurrentLogTick; + + +ISR(TIMER1_COMPA_vect, ISR_BLOCK) +{ + if (CurrentLogTick++ != LOG_INTERVAL_10MS) + return; + + CurrentLogTick = 0; + + if (USB_DeviceState == DEVICE_STATE_Unattached) + { + f_printf(&TempLogFile, "%d Degrees\r\n", Temperature_GetTemperature()); + f_sync(&TempLogFile); + } +} + + +/** Main program entry point. This routine contains the overall program flow, including initial + * setup of all components and the main program loop. + */ +int main(void) +{ + SetupHardware(); + + LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); + + /* Mount and open the log file on the dataflash FAT partition */ + f_mount(0, &DiskFATState); + f_open(&TempLogFile, LOG_FILENAME, FA_OPEN_ALWAYS | FA_WRITE); + f_lseek(&TempLogFile, TempLogFile.fsize); + + /* Write out the log seperator line */ + f_printf(&TempLogFile, "===========================\r\n"); + Temperature_GetTemperature(); // Discard first temperature reading to ensure accuracy + + for (;;) + { + MS_Device_USBTask(&Disk_MS_Interface); + USB_USBTask(); + } +} + +/** Configures the board hardware and chip peripherals for the demo's functionality. */ +void SetupHardware(void) +{ + /* Disable watchdog if enabled by bootloader/fuses */ + MCUSR &= ~(1 << WDRF); + wdt_disable(); + + /* Disable clock division */ + clock_prescale_set(clock_div_1); + + /* Hardware Initialization */ + LEDs_Init(); + SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_SCK_LEAD_FALLING | SPI_SAMPLE_TRAILING | SPI_MODE_MASTER); + Dataflash_Init(); + USB_Init(); + ADC_Init(ADC_REFERENCE_AVCC | ADC_FREE_RUNNING | ADC_PRESCALE_128); + Temperature_Init(); + + /* 10ms interval timer configuration */ + OCR1A = (((F_CPU / 1024) / 100) - 1); + TCCR1A = (1 << WGM01); // CTC mode + TCCR1B = (1 << CS12) | (1 << CS10); // Fcpu/1024 speed + TIMSK1 = (1 << OCIE1A); + + /* Clear Dataflash sector protections, if enabled */ + DataflashManager_ResetDataflashProtections(); +} + +/** Event handler for the library USB Connection event. */ +void EVENT_USB_Device_Connect(void) +{ + LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); + + /* Close the log file so that the host has exclusive filesystem access */ + f_close(&TempLogFile); +} + +/** Event handler for the library USB Disconnection event. */ +void EVENT_USB_Device_Disconnect(void) +{ + LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); + + /* When disconnected from the host, re-open log file so we can resume logging */ + f_mount(0, &DiskFATState); + f_open(&TempLogFile, LOG_FILENAME, FA_OPEN_ALWAYS | FA_WRITE); + f_lseek(&TempLogFile, TempLogFile.fsize); +} + +/** Event handler for the library USB Configuration Changed event. */ +void EVENT_USB_Device_ConfigurationChanged(void) +{ + LEDs_SetAllLEDs(LEDMASK_USB_READY); + + if (!(MS_Device_ConfigureEndpoints(&Disk_MS_Interface))) + LEDs_SetAllLEDs(LEDMASK_USB_ERROR); +} + +/** Event handler for the library USB Unhandled Control Request event. */ +void EVENT_USB_Device_UnhandledControlRequest(void) +{ + MS_Device_ProcessControlRequest(&Disk_MS_Interface); +} + +/** Mass Storage class driver callback function the reception of SCSI commands from the host, which must be processed. + * + * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface configuration structure being referenced + */ +bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) +{ + bool CommandSuccess; + + LEDs_SetAllLEDs(LEDMASK_USB_BUSY); + CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo); + LEDs_SetAllLEDs(LEDMASK_USB_READY); + + return CommandSuccess; +} diff --git a/Projects/TemperatureDataLogger/TempDataLogger.h b/Projects/TemperatureDataLogger/TempDataLogger.h new file mode 100644 index 000000000..502024b44 --- /dev/null +++ b/Projects/TemperatureDataLogger/TempDataLogger.h @@ -0,0 +1,89 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2009. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Header file for TempDataLogger.c. + */ + +#ifndef _TEMP_DATALOGGER_H_ +#define _TEMP_DATALOGGER_H_ + + /* Includes: */ + #include + #include + #include + + #include "Descriptors.h" + + #include "Lib/SCSI.h" + #include "Lib/DataflashManager.h" + #include "Lib/FatFs/ff.h" + + #include + #include + #include + #include + #include + #include + + /* Macros: */ + /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ + #define LEDMASK_USB_NOTREADY LEDS_LED1 + + /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */ + #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3) + + /** LED mask for the library LED driver, to indicate that the USB interface is ready. */ + #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4) + + /** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */ + #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3) + + /** LED mask for the library LED driver, to indicate that the USB interface is busy. */ + #define LEDMASK_USB_BUSY LEDS_LED2 + + /** Filename for the log data when written to the dataflash FAT filesystem. */ + #define LOG_FILENAME "TEMPLOG.txt" + + /** Data log interval between samples, in tens of milliseconds */ + #define LOG_INTERVAL_10MS 1000 + + /* Function Prototypes: */ + void SetupHardware(void); + + void EVENT_USB_Device_Connect(void); + void EVENT_USB_Device_Disconnect(void); + void EVENT_USB_Device_ConfigurationChanged(void); + void EVENT_USB_Device_UnhandledControlRequest(void); + + bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); + +#endif diff --git a/Projects/TemperatureDataLogger/TemperatureDataLogger.txt b/Projects/TemperatureDataLogger/TemperatureDataLogger.txt new file mode 100644 index 000000000..d31e24f36 --- /dev/null +++ b/Projects/TemperatureDataLogger/TemperatureDataLogger.txt @@ -0,0 +1,83 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \mainpage Temperature Datalogger Project + * + * \section SSec_Compat Demo Compatibility: + * + * The following list indicates what microcontrollers are compatible with this demo. + * + * - Series 7 USB AVRs + * - Series 6 USB AVRs + * - Series 4 USB AVRs (with >16KB of FLASH) + * + * \section SSec_Info USB Information: + * + * The following table gives a rundown of the USB utilization of this demo. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
USB Mode:Device
USB Class:Mass Storage Device
USB Subclass:Bulk-Only Transport
Relevant Standards:USBIF Mass Storage StandardUSB Bulk-Only Transport StandardSCSI Primary Commands SpecificationSCSI Block Commands Specification
Usable Speeds:Full Speed Mode
+ * + * \section SSec_Description Project Description: + * + * Temperature Data Logger project. This project is a very basic USB data logger for the current temperature as reported by + * the board's temperature sensor, writing the temperature to a file stored on the board's Dataflash in a FAT filesystem + * each time a specified interval elapses. When inserted into a PC, the datalogger will appear as a standard USB Mass Storage + * device with a single text file, which contains the logged data. + * + * Currently there is no timestamp associated with the logged data; this project can be extended by the addition of a Real + * Time Clock chip to retain the current time/date which could be stored along with each sample. + * + * Due to the host's need for exclusive access to the filesystem, the device will not log samples while connected to a host. + * For the logger to store data, the Dataflash must first be formatted by the host so that it contains a valid FAT filesystem. + * + * \section SSec_Options Project Options + * + * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Define Name:Location:Description:
LOG_FILENAMETempDataLogger.hFilename of the log file to write to on the device's FAT filesystem.
LOG_INTERVAL_10MSTempDataLogger.hTime between each data sample, in tens of milliseconds. Each time this period elapses, a + * temperature sample is taken and the result stored to the Dataflash's FAT filesystem. + *
+ */ diff --git a/Projects/TemperatureDataLogger/makefile b/Projects/TemperatureDataLogger/makefile new file mode 100644 index 000000000..1e495526c --- /dev/null +++ b/Projects/TemperatureDataLogger/makefile @@ -0,0 +1,748 @@ +# Hey Emacs, this is a -*- makefile -*- +#---------------------------------------------------------------------------- +# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al. +# >> Modified for use with the LUFA project. << +# +# Released to the Public Domain +# +# Additional material for this makefile was written by: +# Peter Fleury +# Tim Henigan +# Colin O'Flynn +# Reiner Patommel +# Markus Pfaff +# Sander Pool +# Frederik Rouleau +# Carlos Lamas +# Dean Camera +# Opendous Inc. +# Denver Gingerich +# +#---------------------------------------------------------------------------- +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF. +# +# make extcoff = Convert ELF to AVR Extended COFF. +# +# make program = Download the hex file to the device, using avrdude. +# Please customize the avrdude settings below first! +# +# make dfu = Download the hex file to the device, using dfu-programmer (must +# have dfu-programmer installed). +# +# make flip = Download the hex file to the device, using Atmel FLIP (must +# have Atmel FLIP installed). +# +# make dfu-ee = Download the eeprom file to the device, using dfu-programmer +# (must have dfu-programmer installed). +# +# make flip-ee = Download the eeprom file to the device, using Atmel FLIP +# (must have Atmel FLIP installed). +# +# make doxygen = Generate DoxyGen documentation for the project (must have +# DoxyGen installed) +# +# make debug = Start either simulavr or avarice as specified for debugging, +# with avr-gdb or avr-insight as the front end for debugging. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# make filename.i = Create a preprocessed source file for use in submitting +# bug reports to the GCC project. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + + +# MCU name +MCU = at90usb1287 + + +# Target board (see library "Board Types" documentation, USER or blank for projects not requiring +# LUFA board drivers). If USER is selected, put custom board drivers in a directory called +# "Board" inside the application directory. +BOARD = USBKEY + + +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency in Hz. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +# +# This will be an integer division of F_CLOCK below, as it is sourced by +# F_CLOCK after it has run through any CPU prescalers. Note that this value +# does not *change* the processor frequency - it should merely be updated to +# reflect the processor speed set externally so that the code can use accurate +# software delays. +F_CPU = 8000000 + + +# Input clock frequency. +# This will define a symbol, F_CLOCK, in all source code files equal to the +# input clock frequency (before any prescaling is performed) in Hz. This value may +# differ from F_CPU if prescaling is used on the latter, and is required as the +# raw input clock is fed directly to the PLL sections of the AVR for high speed +# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' +# at the end, this will be done automatically to create a 32-bit value in your +# source code. +# +# If no clock division is performed on the input clock inside the AVR (via the +# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. +F_CLOCK = $(F_CPU) + + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + + +# Target file name (without extension). +TARGET = TempDataLogger + + +# Object files directory +# To put object files in current directory, use a dot (.), do NOT make +# this an empty or blank macro! +OBJDIR = . + + +# Path to the LUFA library +LUFA_PATH = ../../ + + +# LUFA library compile-time options +LUFA_OPTS = -D USB_DEVICE_ONLY +LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8 +LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 +LUFA_OPTS += -D USE_FLASH_DESCRIPTORS +LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)" + + +# List C source files here. (C dependencies are automatically generated.) +SRC = $(TARGET).c \ + Descriptors.c \ + Lib/DataflashManager.c \ + Lib/SCSI.c \ + Lib/FATFs/diskio.c \ + Lib/FATFs/ff.c \ + $(LUFA_PATH)/LUFA/Drivers/Board/Temperature.c \ + $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \ + $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \ + $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c \ + $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/HostChapter9.c \ + $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/LowLevel.c \ + $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Pipe.c \ + $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/Events.c \ + $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c \ + $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c \ + $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c \ + $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/MassStorage.c \ + $(LUFA_PATH)/LUFA/Drivers/USB/Class/Host/MassStorage.c \ + + +# List C++ source files here. (C dependencies are automatically generated.) +CPPSRC = + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# Optimization level, can be [0, 1, 2, 3, s]. +# 0 = turn off optimization. s = optimize for size. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# Debugging format. +# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs. +# AVR Studio 4.10 requires dwarf-2. +# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run. +DEBUG = dwarf-2 + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +# Use forward slashes for directory separators. +# For a directory that has spaces, enclose it in quotes. +EXTRAINCDIRS = $(LUFA_PATH)/ + + +# Compiler flag to set the C Standard level. +# c89 = "ANSI" C +# gnu89 = c89 plus GCC extensions +# c99 = ISO C99 standard (not yet fully implemented) +# gnu99 = c99 plus GCC extensions +CSTANDARD = -std=gnu99 + + +# Place -D or -U options here for C sources +CDEFS = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD) $(LUFA_OPTS) +CDEFS += -DAVR_RESET_LINE_PORT="PORTD" +CDEFS += -DAVR_RESET_LINE_DDR="DDRD" +CDEFS += -DAVR_RESET_LINE_MASK="(1 << 4)" +CDEFS += -DAVR_RESET_PULSE_MS=10 +CDEFS += -DTX_RX_LED_PULSE_MS=30 +CDEFS += -DPING_PONG_LED_PULSE_MS=100 + +# Place -D or -U options here for ASM sources +ADEFS = -DF_CPU=$(F_CPU) + + +# Place -D or -U options here for C++ sources +CPPDEFS = -DF_CPU=$(F_CPU)UL +#CPPDEFS += -D__STDC_LIMIT_MACROS +#CPPDEFS += -D__STDC_CONSTANT_MACROS + + + +#---------------- Compiler Options C ---------------- +# -g*: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +CFLAGS = -g$(DEBUG) +CFLAGS += $(CDEFS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char +CFLAGS += -funsigned-bitfields +CFLAGS += -ffunction-sections +CFLAGS += -fno-inline-small-functions +CFLAGS += -fpack-struct +CFLAGS += -fshort-enums +CFLAGS += -Wall +CFLAGS += -Wstrict-prototypes +CFLAGS += -Wundef +#CFLAGS += -fno-unit-at-a-time +#CFLAGS += -Wunreachable-code +#CFLAGS += -Wsign-compare +CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + + +#---------------- Compiler Options C++ ---------------- +# -g*: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +CPPFLAGS = -g$(DEBUG) +CPPFLAGS += $(CPPDEFS) +CPPFLAGS += -O$(OPT) +CPPFLAGS += -funsigned-char +CPPFLAGS += -funsigned-bitfields +CPPFLAGS += -fpack-struct +CPPFLAGS += -fshort-enums +CPPFLAGS += -fno-exceptions +CPPFLAGS += -Wall +CFLAGS += -Wundef +#CPPFLAGS += -mshort-calls +#CPPFLAGS += -fno-unit-at-a-time +#CPPFLAGS += -Wstrict-prototypes +#CPPFLAGS += -Wunreachable-code +#CPPFLAGS += -Wsign-compare +CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst) +CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +#CPPFLAGS += $(CSTANDARD) + + +#---------------- Assembler Options ---------------- +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +# -listing-cont-lines: Sets the maximum number of continuation lines of hex +# dump that will be displayed for a given single line of source input. +ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100 + + +#---------------- Library Options ---------------- +# Minimalistic printf version +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires MATH_LIB = -lm below) +PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt + +# If this is left blank, then it will use the Standard printf version. +PRINTF_LIB = +#PRINTF_LIB = $(PRINTF_LIB_MIN) +#PRINTF_LIB = $(PRINTF_LIB_FLOAT) + + +# Minimalistic scanf version +SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min + +# Floating point + %[ scanf version (requires MATH_LIB = -lm below) +SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt + +# If this is left blank, then it will use the Standard scanf version. +SCANF_LIB = +#SCANF_LIB = $(SCANF_LIB_MIN) +#SCANF_LIB = $(SCANF_LIB_FLOAT) + + +MATH_LIB = -lm + + +# List any extra directories to look for libraries here. +# Each directory must be seperated by a space. +# Use forward slashes for directory separators. +# For a directory that has spaces, enclose it in quotes. +EXTRALIBDIRS = + + + +#---------------- External Memory Options ---------------- + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff + +EXTMEMOPTS = + + + +#---------------- Linker Options ---------------- +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref +LDFLAGS += -Wl,--relax +LDFLAGS += -Wl,--gc-sections +LDFLAGS += $(EXTMEMOPTS) +LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) +#LDFLAGS += -T linker_script.x + + + +#---------------- Programming Options (avrdude) ---------------- + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# +AVRDUDE_PROGRAMMER = jtagmkII + +# com1 = serial port. Use lpt1 to connect to parallel port. +AVRDUDE_PORT = usb + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE_COUNTER = -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_NO_VERIFY = -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +#---------------- Debugging Options ---------------- + +# For simulavr only - target MCU frequency. +DEBUG_MFREQ = $(F_CPU) + +# Set the DEBUG_UI to either gdb or insight. +# DEBUG_UI = gdb +DEBUG_UI = insight + +# Set the debugging back-end to either avarice, simulavr. +DEBUG_BACKEND = avarice +#DEBUG_BACKEND = simulavr + +# GDB Init Filename. +GDBINIT_FILE = __avr_gdbinit + +# When using avarice settings for the JTAG +JTAG_DEV = /dev/com1 + +# Debugging port used to communicate between GDB / avarice / simulavr. +DEBUG_PORT = 4242 + +# Debugging host used to communicate between GDB / avarice / simulavr, normally +# just set to localhost unless doing some sort of crazy debugging when +# avarice is running on a different computer. +DEBUG_HOST = localhost + + + +#============================================================================ + + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AR = avr-ar rcs +NM = avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +REMOVEDIR = rm -rf +COPY = cp +WINSHELL = cmd + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_COMPILING_CPP = Compiling C++: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: +MSG_CREATING_LIBRARY = Creating library: + + + + +# Define all object files. +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o) + +# Define all listing files. +LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst) + + +# Compiler flags to generate dependency files. +GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d + + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + + + +# Default target. +all: begin gccversion sizebefore build checkinvalidevents showliboptions showtarget sizeafter end + +# Change the build target to build a HEX file or a library. +build: elf hex eep lss sym +#build: lib + + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym +LIBNAME=lib$(TARGET).a +lib: $(LIBNAME) + + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) $(MCU_FLAG) $(FORMAT_FLAG) $(TARGET).elf +MCU_FLAG = $(shell $(SIZE) --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) ) +FORMAT_FLAG = $(shell $(SIZE) --help | grep -- --format=.*avr > /dev/null && echo --format=avr ) + +sizebefore: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +$(LUFA_PATH)/LUFA/LUFA_Events.lst: + @make -C $(LUFA_PATH)/LUFA/ LUFA_Events.lst + +checkinvalidevents: $(LUFA_PATH)/LUFA/LUFA_Events.lst + @echo + @echo Checking for invalid events... + @$(shell) avr-nm $(OBJ) | sed -n -e 's/^.*EVENT_/EVENT_/p' | \ + grep -F -v --file=$(LUFA_PATH)/LUFA/LUFA_Events.lst > InvalidEvents.tmp || true + @sed -n -e 's/^/ WARNING - INVALID EVENT NAME: /p' InvalidEvents.tmp + @if test -s InvalidEvents.tmp; then exit 1; fi + +showliboptions: + @echo + @echo ---- Compile Time Library Options ---- + @for i in $(LUFA_OPTS:-D%=%); do \ + echo $$i; \ + done + @echo -------------------------------------- + +showtarget: + @echo + @echo --------- Target Information --------- + @echo AVR Model: $(MCU) + @echo Board: $(BOARD) + @echo Clock: $(F_CPU)Hz CPU, $(F_CLOCK)Hz Master + @echo -------------------------------------- + + +# Display compiler version information. +gccversion : + @$(CC) --version + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + +flip: $(TARGET).hex + batchisp -hardware usb -device $(MCU) -operation erase f + batchisp -hardware usb -device $(MCU) -operation loadbuffer $(TARGET).hex program + batchisp -hardware usb -device $(MCU) -operation start reset 0 + +dfu: $(TARGET).hex + dfu-programmer $(MCU) erase + dfu-programmer $(MCU) flash --debug 1 $(TARGET).hex + dfu-programmer $(MCU) reset + +flip-ee: $(TARGET).hex $(TARGET).eep + $(COPY) $(TARGET).eep $(TARGET)eep.hex + batchisp -hardware usb -device $(MCU) -operation memory EEPROM erase + batchisp -hardware usb -device $(MCU) -operation memory EEPROM loadbuffer $(TARGET)eep.hex program + batchisp -hardware usb -device $(MCU) -operation start reset 0 + $(REMOVE) $(TARGET)eep.hex + +dfu-ee: $(TARGET).hex $(TARGET).eep + dfu-programmer $(MCU) flash-eeprom --debug 1 --suppress-bootloader-mem $(TARGET).eep + dfu-programmer $(MCU) reset + + +# Generate avr-gdb config/init file which does the following: +# define the reset signal, load the target file, connect to target, and set +# a breakpoint at main(). +gdb-config: + @$(REMOVE) $(GDBINIT_FILE) + @echo define reset >> $(GDBINIT_FILE) + @echo SIGNAL SIGHUP >> $(GDBINIT_FILE) + @echo end >> $(GDBINIT_FILE) + @echo file $(TARGET).elf >> $(GDBINIT_FILE) + @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE) +ifeq ($(DEBUG_BACKEND),simulavr) + @echo load >> $(GDBINIT_FILE) +endif + @echo break main >> $(GDBINIT_FILE) + +debug: gdb-config $(TARGET).elf +ifeq ($(DEBUG_BACKEND), avarice) + @echo Starting AVaRICE - Press enter when "waiting to connect" message displays. + @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \ + $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT) + @$(WINSHELL) /c pause + +else + @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \ + $(DEBUG_MFREQ) --port $(DEBUG_PORT) +endif + @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT = $(OBJCOPY) --debugging +COFFCONVERT += --change-section-address .data-0x800000 +COFFCONVERT += --change-section-address .bss-0x800000 +COFFCONVERT += --change-section-address .noinit-0x800000 +COFFCONVERT += --change-section-address .eeprom-0x810000 + + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -z -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + + +# Create library from object files. +.SECONDARY : $(TARGET).a +.PRECIOUS : $(OBJ) +%.a: $(OBJ) + @echo + @echo $(MSG_CREATING_LIBRARY) $@ + $(AR) $@ $(OBJ) + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +$(OBJDIR)/%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create object files from C++ source files. +$(OBJDIR)/%.o : %.cpp + @echo + @echo $(MSG_COMPILING_CPP) $< + $(CC) -c $(ALL_CPPFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C++ source files. +%.s : %.cpp + $(CC) -S $(ALL_CPPFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +$(OBJDIR)/%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + +# Create preprocessed source for use in sending a bug report. +%.i : %.c + $(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ + + +# Target: clean project. +clean: begin clean_list clean_binary end + +clean_binary: + $(REMOVE) $(TARGET).hex + +clean_list: + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET)eep.hex + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lss + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVE) $(SRC:.c=.i) + $(REMOVE) InvalidEvents.tmp + $(REMOVEDIR) .dep + +doxygen: + @echo Generating Project Documentation... + @doxygen Doxygen.conf + @echo Documentation Generation Complete. + +clean_doxygen: + rm -rf Documentation + +# Create object files directory +$(shell mkdir $(OBJDIR) 2>/dev/null) + + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + + +# Listing of phony targets. +.PHONY : all checkinvalidevents showliboptions \ +showtarget begin finish end sizebefore sizeafter \ +gccversion build elf hex eep lss sym coff extcoff \ +program dfu flip flip-ee dfu-ee clean debug \ +clean_list clean_binary gdb-config doxygen \ No newline at end of file diff --git a/Projects/makefile b/Projects/makefile index 578e5217a..c871f2861 100644 --- a/Projects/makefile +++ b/Projects/makefile @@ -29,6 +29,9 @@ all: make -C MissileLauncher clean make -C MissileLauncher all + make -C TemperatureDataLogger clean + make -C TemperatureDataLogger all + make -C USBtoSerial clean make -C USBtoSerial all @@ -41,5 +44,6 @@ all: make -C LEDNotifier $@ make -C Magstripe $@ make -C MissileLauncher $@ + make -C TemperatureDataLogger $@ make -C USBtoSerial $@ make -C XPLAINBridge $@ -- cgit v1.2.3